
Security News
Browserslist-rs Gets Major Refactor, Cutting Binary Size by Over 1MB
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
http-signature-server
Advanced tools
Implementation of the server side of the IETF draft "Signing HTTP Messages"
HTTP server agnostic Python implementation of the server side of the IETF draft "Signing HTTP Messages", with no dependencies other than the Python standard library, although cryptography would typically be used in client code to verify signatures using a public key.
See http-signature-client for a compatible client-side implementation.
pip install http-signature-server
from http_signature_server import verify
def verify(key_id, signature, signature_input):
# If the key_id is not found, return None
# If the key_id is found and the signature verifies the input, return True
# If the key_is is found and the signature does not verify the input, return False
error, (key_id, verified_headers) = verify_headers(verify, max_skew, method, path, headers)
if error is not None:
# Return error or raise exception as needed
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_public_key
public_key = \
b'-----BEGIN PUBLIC KEY-----\n' \
b'MCowBQYDK2VwAyEAe9+zIz+CH9E++J0qiE6aS657qzxsNWIEf2BZcUAQF94=\n' \
b'-----END PUBLIC KEY-----\n'
public_key = load_pem_public_key(public_key, backend=default_backend())
def verify(key_id, signature, signature_input):
# Could use the supplied key_id to lookup the public key
try:
public_key.verify(signature, signature_input)
except InvalidSignature:
return False
return True
# method, path, and headers would be taken from the incoming HTTP request
error, (key_id, verified_headers) = verify_headers(verify, 10, method, path, headers)
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.serialization import Encoding, NoEncryption, PrivateFormat, PublicFormat
private_key = Ed25519PrivateKey.generate()
print(private_key.private_bytes(encoding=Encoding.PEM, format=PrivateFormat.PKCS8, encryption_algorithm=NoEncryption()))
print(private_key.public_key().public_bytes(encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo))
verify
- A callable taking a str
key_id
and bytes
signature
and signature_input
. It must return True
if key_id
is known and signature
/signature_input
is verified, for example by a corresponding public key; return False
if key_id
is known but the signature
/signature_input
is not verified; return None
otherwise.
max_skew
- A maximum integer number of seconds difference from the time an incoming signature claimed to be constructed, and the current time.
method
- The HTTP method of the request, such as GET
or POST
.
path
- The full path of the request, including any query string.
headers
- A tuple of (key, value) pairs of HTTP headers to attempt to verify.
A tuple error, (key_id, verified_headers)
.
error
- If the request is verified, None
. Otherwise a str
containing a short reason in English as to why verification failed.
key_id
- If the request is verified, the keyId
from the incoming request. Otherwise, None
.
verified_headers
- If the request is verified, the (key, value) HTTP header pairs that were verified by the signature; this will be a sub-tuple of the headers
parameter. Otherwise, None
.
A deliberate subset of the signature algorithm is implemented/enforced:
(request-target)
pseudo-header is required and verified;created
parameter is required, and the corresponding (created)
pseudo-header must be signed;headers
parameter is required;expires
parameter, if sent, must not correspond to a signed (expires)
pseudo-header;algorithm
parameter is ignored if sent.There are a few places where the implementation is technically, and deliberately, non-conforming.
The (created)
pseudo-header: if this is in the future from the server's point of view, even 1 second, according to the spec verification should fail. Instead, there is a configurable maximum time skew that applies to the future as well as the past.
The expires
parameter: if this is sent and in the past from the server's point of view, according to the spec verification should fail.
The algorithm
parameter: if it's sent but does not match what the server expects, according to the spec verification should fail.
It is assumed that the (created)
and (request-target)
pseudo-headers were prepended to the list of real HTTP headers before canonicalisation at the client. This fact only makes a difference in the edge case of real HTTP headers called (created)
or (request-target)
.
FAQs
Implementation of the server side of the IETF draft "Signing HTTP Messages"
We found that http-signature-server demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Research
Security News
Eight new malicious Firefox extensions impersonate games, steal OAuth tokens, hijack sessions, and exploit browser permissions to spy on users.
Security News
The official Go SDK for the Model Context Protocol is in development, with a stable, production-ready release expected by August 2025.