Detect tampered signed values
When you transmit data to a client and expect to receive it back unchanged, you must ensure the data has not been tampered with. If a user modifies a signed value—for example, by changing a user ID in a cookie—itsdangerous detects this mismatch during verification and prevents the application from processing the corrupted data.
The Signer class in itsdangerous.signer provides the core mechanism for this protection. It appends a cryptographic signature to your data, which is derived from the data itself and a secret key.
Signing and Verifying Data
To protect a value, you use the Signer.sign method. This produces a byte string containing the original data, a separator (defaulting to .), and the signature. When the data returns, Signer.unsign verifies the signature. If the signature is valid, it returns the original payload; otherwise, it raises an exception.
Internally, Signer.unsign splits the input by the separator and uses Signer.verify_signature to check the provided signature against a newly generated one. If they do not match, it raises itsdangerous.exc.BadSignature. This exception object includes a payload attribute, which contains the data that failed verification, allowing you to inspect the tampered value if necessary.
Detecting Tampering
The following example demonstrates the complete lifecycle of a signed value, including how itsdangerous reacts when a single byte of the signed string is altered.
from itsdangerous import BadSignature, Signer
# Initialize a Signer with a fixed secret key
signer = Signer(b"secret-key")
# Original data to be protected
original_data = b"user-id:100"
# Create a signed value
signed_value = signer.sign(original_data)
# Verify the unchanged value
unsigned_data = signer.unsign(signed_value)
assert unsigned_data == original_data
# Simulate tampering by changing one byte of the signed value
tampered_value = signed_value[:-1] + (b"a" if signed_value[-1:] != b"a" else b"b")
# Attempting to unsign tampered data raises BadSignature
try:
signer.unsign(tampered_value)
except BadSignature as e:
# The exception provides access to the tampered payload
assert e.payload is not None
When unsign encounters a tampered value, it performs a constant-time comparison of the signatures to prevent timing attacks, then raises the exception to signal that the data is untrustworthy. By catching BadSignature, your application can safely reject invalid requests.