Skip to main content

Detect tampered signed values

When you transmit data to a client and expect it back unchanged, you must ensure that 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. When you attempt to retrieve the original value using unsign, the Signer recalculates the signature and compares it to the one provided. If even a single byte of the signed string is altered, the signatures will not match, and the unsign method will raise a BadSignature exception.

The following example demonstrates how to initialize a Signer, generate a signed value, and verify that tampering is correctly detected.

from itsdangerous import BadSignature, Signer

# Initialize Signer with a fixed secret key
signer = Signer(b"secret-key")

# Sign fixed bytes
original = b"correct-data"
signed = signer.sign(original)

# Verify the unchanged value with unsign (first call)
unsigned = signer.unsign(signed)
assert unsigned == original

# Change one byte of the signed value to simulate tampering
tampered = signed[:-1] + (b"X" if signed[-1:] != b"X" else b"Y")

# Prove unsign raises itsdangerous.BadSignature (second call)
try:
signer.unsign(tampered)
except BadSignature as exc:
# The exception provides access to the (untrusted) payload
assert exc.payload == original

Internally, Signer.unsign splits the input string using the configured separator (defaulting to .). It extracts the payload and the signature, then calls verify_signature. This method iterates through the available secret_keys (supporting key rotation) and uses the SigningAlgorithm (typically HMACAlgorithm) to check the validity. If no key produces a matching signature, unsign raises BadSignature. The payload attribute on the exception allows you to inspect the data that failed verification, which can be useful for logging or debugging while still treating the data as untrusted.