Home / Knowledge hub / JWT signature verification
Knowledge hub
JWT signature verification
Checking a token's signature properly before trusting anything inside it.
What it means
A JSON Web Token carries claims, such as who the user is and what role they hold, in a form that the holder can read and, if nothing stops them, change. The signature is what stops that. Verification means recomputing it with the right key and refusing the token if it does not match.
Decoding a token and verifying it are different steps, and the difference is easy to miss. Decoding just reads the contents, and anyone can do it. Only verification tells you the contents came from your issuer and were not altered on the way.
Why it matters
If an app reads claims without verifying the signature, a user can edit their own token. They change a role from user to admin, or an account id to someone else's, and the app believes them. That is privilege escalation with nothing more than a text editor and a little patience.
The consequences match whatever the claims control: other customers' data, admin functions, paid features. It also tends to survive review, because sign-in still works normally for every ordinary customer. Only a test with a changed token shows the gap, which is why it is worth running.
How it shows up
Typical failures are code that decodes but never verifies, a library that accepts the none algorithm, an algorithm taken from the token header instead of from your configuration, and keys fetched from a place the token itself names. RFC 8725 sets out the best practices for these. See the none algorithm and algorithm confusion.
A sound check fixes the accepted algorithm in configuration, verifies the signature before reading any claim, then validates the issuer, audience and expiry. Keep signing keys out of the front end and rotate them. Test by sending tokens that are altered, unsigned or expired.
Questions people ask
JWT signature verification, answered
Is decoding a JWT the same as verifying it?
No. Decoding only reads the token, which anyone can do because the contents are encoded, not encrypted.
Verification recomputes the signature with the correct key and rejects the token if it does not match.
What should be checked besides the signature?
The issuer, the audience, the expiry and not-before times, and any claims your app depends on. RFC 8725 gives the detail.
A valid signature on a token meant for another service is still the wrong token.
Why shouldn't the token choose its own algorithm?
Because the header is part of the token, which an attacker controls. If you let it choose, they can choose none or a weaker option.
Your server should decide which algorithms it accepts and ignore the header's preference.
Does a signed JWT hide its contents?
No. A signed token is readable by anyone who holds it. Put nothing in it you would not show the user.
If you need secrecy, use an encrypted token, which is a separate format.
How do we test our JWT handling?
Change a claim and resubmit, remove the signature, switch the algorithm and replay an expired token. Each should be refused.
If any is accepted, the signature check is missing or weak.
Related
Terms that sit next to this one
JWT
A signed token a client carries to prove who is signed in.
JWT none algorithm
A token that claims to need no signature, accepted by a careless library.
JWT algorithm confusion
Tricking a server into verifying a token with the wrong signing method.
Digital signature
A value that proves who produced data and that it has not changed since.
Token
A string that stands in for an identity or a permission.
What if the token was edited?
A token your app believes without checking is a door left on the latch. We send altered, unsigned and expired tokens to your API and report what it accepted, with the request and response. Book a pilot on one app.
Or start with a $199 pilot on one application: thirty days, success criteria agreed before day one, credited against the annual if you convert.