Skip to main content

Detect tampered signed values

When you transmit data to a client and expect to receive it back unchanged, you must be able to detect if the client modified the data. If a user modifies a signed value, itsdangerous identifies the mismatch during verification and prevents the application from processing the tampered data.

The Signer class in itsdangerous handles this by appending a cryptographic signature to your bytes. When you call Signer.sign, the library generates a signature based on your secret_key and the input data. Later, when you call Signer.unsign, the library recalculates the signature for the received payload and compares it to the attached signature.

If the payload has been altered—even by a single byte—the signatures will not match. In this scenario, Signer.unsign raises an itsdangerous.BadSignature exception. This exception object contains a payload attribute, which allows you to inspect the tampered data if necessary, though it should not be trusted for application logic.

from itsdangerous import BadSignature, Signer

signer = Signer(b"secret-key")
value = b"my-data"

# Call sign exactly once
signed_value = signer.sign(value)

# Call unsign exactly twice
# 1. For the valid signed value
valid_result = signer.unsign(signed_value)
assert valid_result == value

# 2. For a tampered value inside a try block
tampered_value = signed_value[:-1] + b"!"
try:
signer.unsign(tampered_value)
assert False, "Should have raised BadSignature"
except BadSignature as e:
assert e.payload == value

The Signer uses a separator (defaulting to .) to divide the payload from the signature. Internally, Signer.unsign splits the string at the last occurrence of this separator, verifies the signature using Signer.verify_signature, and returns the payload only if the check passes. By catching BadSignature, your application can safely reject requests that contain manipulated tokens or session data.