JWT (JSON Web Tokens) have become a default choice for authentication and authorisation in modern systems.
They are widely adopted because they are:
- Stateless
- Scalable
- Easy to integrate across services
But in real-world environments, especially distributed systems, JWT often introduces subtle security risks that are not immediately visible.
Most JWT implementations are cryptographically correct…
but architecturally flawed.
This post explains:
- How JWT actually works
- Where implementations go wrong
- Real-world failure scenarios
- How to design JWT usage securely
1. What JWT Really Is
A JWT is a signed token, not an encrypted one.
It guarantees:
- Integrity (data hasn’t been modified)
- Authenticity (issued by a trusted entity)
It does not guarantee:
- Confidentiality
- Correct usage across systems
- Authorisation correctness
2. JWT Structure
A JWT consists of three parts:
HEADER.PAYLOAD.SIGNATURE
Header
Defines metadata like algorithm used for signing.
Payload (Claims)
Contains:
- Identity (user_id)
- Authorisation (role)
- Context (issuer, audience)
- Expiry
⚠️ Important: Payload is base64 encoded, not encrypted.
Signature
Generated using:
- Header + Payload
- Secret or private key
This ensures the token hasn’t been tampered with.
3. How JWT Verification Works
When a request arrives:
- Token is extracted
- Signature is verified
- Claims are validated
4. The Most Dangerous Assumption
Most systems assume:
“If the signature is valid, the token is trustworthy.”
This is incomplete.
A valid JWT only proves:
- It was issued by a trusted authority
- It was not modified
It does not prove:
- It is intended for this service
- It represents current permissions
- It should still be accepted
5. Context Matters More Than Signature
JWT security depends heavily on context validation, especially:
-
iss(Issuer) → Who created the token -
aud(Audience) → Who should accept it -
exp→ Is it still valid
If these are not enforced strictly, tokens become:
- Reusable across services
- Valid in unintended contexts
6. Real-World Failure: Cross-Service Token Misuse
Scenario
- Auth service issues JWT
- Multiple backend services trust same signing key
- Services validate signature only
Vulnerable Flow: An attacker logs into Service A, receives a valid JWT (aud=ServiceA) and then sends that same JWT to Service B. Because Service B only verifies the signature, access is granted.
Why This Happens:
Because:
- Token is valid
- Signature is correct
- But
audienceis ignored
Secure Flow:
7. Common JWT Security Pitfalls
- No Audience Validation: Tokens become reusable across services.
- No Issuer Validation: Untrusted tokens may be accepted.
- Shared Signing Keys: Compromise of one service impacts all.
- Authorisation Stored in Token: Outdated roles remain valid until expiry.
- No Revocation Mechanism: Tokens remain valid even after compromise.
- Long Expiry Tokens: Act like long-lived credentials.
- Insecure Storage (localStorage): Exposed to XSS → token theft.
- Algorithm Confusion: Trusting token header can lead to bypass.
- Logging Tokens: Leaked tokens = full access.
- Over-Permissive Tokens: Tokens used beyond intended purpose.
8. Why These Issues Exist
JWT removes server-side state.
This improves scalability but removes:
- Central control
- Immediate revocation
- Context enforcement
JWT simplifies systems, but shifts responsibility to design.
9. Threat Modelling Checklist (Design Phase)
Before implementing JWT, ask these:
1. Trust Boundaries
- Which service issues tokens?
- Which services accept them?
- Can tokens be reused across services?
- Is
audstrictly enforced?
2. Key Management
- Are signing keys shared across services?
- What happens if one service is compromised?
- Are keys rotated regularly?
3. Token Scope
- What is this token intended for?
- Is it scoped per service?
- Does it carry excessive permissions?
4. Lifecycle Management
- What is token expiry duration?
- Can tokens be revoked?
- What happens if user access changes?
5. Payload Design
- Are roles embedded in token?
- What happens when roles change?
- Is sensitive data exposed?
6. Client-Side Risks
- Where is the token stored?
- Can JavaScript access it?
- Is it exposed in logs or URLs?
7. Validation Logic
- Are
iss,aud,expvalidated? - Is algorithm strictly enforced?
- Are headers trusted blindly?
8. Abuse Scenarios
- Can tokens be replayed?
- Can they be reused across devices/services?
- Can attackers pivot using valid tokens?
9. Detection & Monitoring
- Can abnormal token usage be detected?
- Are logs secure?
- Is token misuse visible?
10. Failure Planning
- What if signing key is leaked?
- What if token is stolen?
- Do you have containment strategy?
10. Secure JWT Design Principles
- Validate context, not just signature
- Scope tokens per service
- Use separate signing keys where possible
- Keep tokens short-lived
- Avoid storing sensitive data in payload
- Implement monitoring and anomaly detection
Closing Insight
If you’re using JWT in production, don’t just ask:
“Is this token valid?”
Ask:
“Is this token valid for this system, at this moment, for this purpose?”




Top comments (0)