AI built your auth check. You log in, the right pages load, you shipped. What you actually shipped accepts a token that anyone can rewrite — including the part that says they’re an admin.
What you shipped
The handler reads the token with decode instead of verify. decode just unpacks the payload; it never checks the signature that proves the token came from you.

How anyone exploits it
A JWT is just base64. Open yours, change "role":"user" to "role":"admin", re-encode, and send it. Because the server only decodes, it never notices the signature no longer matches — it just trusts the new payload. Instant admin.
Why you won’t catch it
You log in normally, get a valid token, and everything works. The forged token only appears when someone edits theirs by hand — which you’d never do and a normal test never does.
Why AI does it
decode is the shortest call that gets the user out of a token, and it works perfectly for honest tokens. The signature check is an extra step the happy path runs fine without.
The fix
Use verify with your secret, not decode. verify checks the signature and rejects anything tampered with:
const user = jwt.verify(token, process.env.SECRET)

Check your app
- Every token is read with
verify(or your library’s verifying call), neverdecode. - The signing secret is strong and server-only.
- Reject tokens with
alg: noneor a mismatched algorithm.
The bigger problem
A senior dev catches this by reflex. But if nobody senior reads the code, the broken version ships — it works in every test, because every test takes the happy path. The author and the reviewer are the same model with the same blind spot.
That’s the gap Velify is built to close: it reads your project and flags exactly this, in plain language, no terminal.
