Skip to content
All writing
Engineering · 2 min read

Seven Blind Spots Behind a JWT Audit

A friend's JWT auth worked. Signatures verified. But seven security gaps sat wide open. These notes are the result of that audit.

“A signed JWT is not a secure JWT. The signature answers one question: was it tampered with?”

The situation

A friend built a multiplayer side project with vibe coding. JWT auth worked. Users could log in and call APIs. I read through his code and noticed jwt.verify did not pin the algorithm.

I told him this was a problem. He looked confused: “The signature passes. Why isn’t that enough?”

His question made me realize I could not fully explain it either. I knew something was off, but not the full picture. So I studied the entire JWT security model from scratch, then came back and walked him through it. I found seven open gaps:

  • No algorithm pin. Attacker can forge signatures.
  • No iss. Tokens signed by other services pass verification.
  • No aud. Refresh tokens work as access tokens.
  • No exp with rotation. Stolen tokens work forever.
  • No timing-safe comparison. Side-channel attacks can guess the secret byte by byte.

I spent a week fixing all of them. These seven notes are the result of that audit.

Seven pieces

1. What is a JWT

A token has three parts: header, payload, signature. Anyone can read the first two. The signature is the only part that needs a key. JWT is not encryption.

Read more in What Is a JWT: Three Parts and a Signature.

2. Symmetric vs asymmetric signing

HS256 uses one shared secret. RS256 uses two keys: private to sign, public to verify. The choice depends on one question: can the verifier be trusted with signing power?

Read more in Symmetric vs Asymmetric Signing.

3. Six standard claims

The signature only blocks tampering. Six claims each block a different attack path. Skip any one, and the corresponding gap opens.

Read more in Six Standard Claims, Each Blocks One Gap.

4. The iss claim

iss marks who signed the token. Without it, any service that holds the same secret can sign a valid token.

Read more in The iss Claim: Issuer Identity.

5. Algorithm confusion and the none attack

The alg field in the JWT header is client-controlled. An attacker can change it to none or confuse the signing type. Pin the algorithm server-side to block both attacks.

Read more in Algorithm Confusion and the none Attack.

6. Access and refresh token rotation

One token forces a tradeoff between security and UX. Two tokens resolve it. Combined with reuse detection, the attack window shrinks to 15 minutes.

Read more in Access and Refresh Token Rotation.

7. Timing-safe comparison

Strict equality stops at the first mismatched byte. Response time reveals how many bytes matched. timingSafeEqual runs through the full length in constant time.

Read more in Timing-Safe Comparison: Side-Channel Defense.

Takeaway

“The signature is step one, not the finish line. Six claims plus timing-safe comparison form the real defense.”


References:

Related: What Is a JWT · Symmetric vs Asymmetric Signing · Six Standard Claims · The iss Claim · Algorithm Confusion and the none Attack · Access and Refresh Token Rotation · Timing-Safe Comparison

Tags #jwt #security #authentication
// connect

Be brave | Be wise | Be grateful

21 BreakinCode

// elsewhere
LinkedInMedium (lang: en)Life RecordYoutube
wh:~$William Hung· © 2026 Taipei · GMT+8 · Available for collaboration