You did not get a security alert. You got a Slack message saying something is broken. A service returning 403s out of nowhere. An API behaving inconsistently across environments. A job that worked in staging silently dying in production. Standard SRE territory, except the root cause is not in your infra.
If you are an SRE or platform engineer, JWTs are probably not your code. But when they get abused, the symptoms land on your plate anyway. In distributed systems, a single manipulated or replayed token can ripple across services before anyone connects the dots and by the time it surfaces as an incident, it looks like an infra problem.
This is a diagnostic guide for that exact situation. Built for SREs who need to move from symptom to root cause fast, without waiting for the security team to hand them a verdict.
60 second Quick Check: Signs of JWT Abuse
Run through this checklist based on what you are currently observing. This is often the fastest way to confirm whether what you are seeing is normal usage or token misuse.
- Are you seeing the same token used from different IPs or locations within a short time window?
- Does a token appear to be active from multiple sessions in parallel?
- Has a token that usually generates low traffic suddenly started making high-frequency API calls?
- Are there changes in User-Agent or device characteristics for the same token?
- Is activity continuing even when the user is inactive or outside normal usage hours?
- Do you see refresh tokens being reused after they should have been rotated?
- Is a single token accessing multiple services or endpoints in ways that do not match normal flows?
If you are seeing a combination of these signals, you are likely dealing with JWT token misuse rather than normal user activity. At this point, focus on whether the token is being reused across contexts or has been exposed.
Next: If the checklist signals match what you are seeing, use the sections below to interpret the activity and determine whether it points to replay, token exposure, or a broader authentication issue.
Before you go deeper, keep this in mind: token abuse often blends into normal application activity. A spike in API calls, unusual access patterns, or tokens appearing across multiple services can easily be dismissed as expected behavior, especially when requests are valid, and authentication is not failing.
This is where misuse gets overlooked. What appears to be a backend job, an integration, or a change in usage can also be a valid token being reused without detection.
That is why this guide starts with quick behavioral checks and then moves into deeper validation. Once you separate normal usage from misuse patterns, the next steps are whether to revoke tokens, enforce controls, or monitor further become much clearer.
What JWT Abuse Actually Means
JSON Web Tokens (JWT) abuse rarely appears as a single, obvious attack. In most cases, you will see valid tokens being used in ways that do not align with expected application behavior.
A JWT is accepted as proof that authentication has already happened, and once it passes validation, the request is trusted. There is no built-in check to confirm whether the token is still being used by the same client or under the same conditions it was issued for.
That assumption is where things start to break. If someone else gets access to that token, whether by reuse, extraction, or manipulation, they can operate as the user without going through authentication again. From your system’s perspective, nothing is technically wrong. The token is valid, so the request is allowed.
This opens up multiple paths for abuse. You may see tokens being reused across sessions, payloads being modified when validation is weak, or entirely new tokens being accepted due to misconfigured verification. In other cases, tokens are simply exposed and reused without any change to their structure.
Most systems are built to protect the login steps. JWT abuse happens after that step has already succeeded.
Why JWT-Based Systems Are a High-Value Target
Modern APIs rely on JWTs to handle authentication without maintaining server-side sessions. Once a token is issued, it carries identity and access information that downstream services use to allow requests.
Because the token operates independently after issuance, there is no continuous identity verification tied to each request. Controls such as MFA and SSO are only applied during login, and do not come into play once the token is being used.
In addition, tokens often move across multiple APIs and integrations, where they are accepted as long as validation checks pass. The system focuses on whether the token is valid, not on how or where it is being used.
As a result, once a token is issued, requests carrying it are treated as legitimate by default. This is why a significant portion of attacks now originate from authenticated sessions, and why token abuse is more difficult to detect than credential-based attacks.
Common JWT Abuse Scenarios: What You Should Be Looking For
Even with JWT abuse, you will see valid tokens, successful requests, and no clear authentication failures. The issue becomes visible when access continues in ways that do not align with expected user behavior.
The fastest way to approach this is to follow how the issue surfaces, then trace it back step by step.
Layer 1: What You See in Traffic (Symptoms)
- Token Replay (Session Hijacking Without Login)
You are seeing authenticated requests with no validation failures. The token is valid, not expired, and the claims look correct. What stands out is how that token is being used.
The same token appears across different IPs within seconds, or you see activity that does not match a single user session. In some cases, requests continue even when the user is inactive. There is no new login tied to this activity.
From the system’s perspective, everything checks out, which is why this is often missed.
How to trace it:
Pull logs for that specific token and check its usage across requests.
token_id: eyJhbGci...xZ9
10:42:11 - Request from IP 103.21.45.12 — /api/orders
10:42:14 - Request from IP 185.93.22.67 — /api/orders
10:42:18 - Request from IP 103.21.45.12 — /api/profile
The same token hitting two geographically distinct IPs within seconds is not a routing anomaly. That is the same credential being used from two different locations simultaneously. Cross-reference the token’s issued time against this activity. If there was no re-authentication between these requests, you are looking at token reuse, not a normal session.
What to do next: Invalidate the token immediately. If your system does not support token revocation, flag the token ID and block it at the gateway level while you investigate further.
- Scope and Claims Abuse
Requests are valid and the token is accepted. The difference shows up in the level of access. You may see a token accessing endpoints that do not match its intended role. For example, a token issued for a standard user begins accessing administrative APIs or internal services. There is no failure signal here. The request succeeds because the token is accepted.
How to trace it:
Decode the token and compare its claims with the APIs being accessed.
token_id: eyJhbGci...pQ2
Decoded token:
role: user
scope: read_profile
Observed access:
GET /api/profile
GET /api/admin/users
GET /api/internal/reports
The token is issued with user-level permissions, limited to profile access. The same token is now calling administrative and internal endpoints. That shift is not expected within a single session. The token has not changed, but the access pattern has.
Cross-check how your application enforces roles at the API layer. If these requests are succeeding without additional validation, access control is not being applied correctly for that token.
What to do next:
Stop relying on token presence alone. Enforce strict role and scope checks at the API level and block access that does not align with assigned permissions.
Layer 2: How the Token Got There (Origin)
- Credential Stuffing Leading to Token Abuse
You may first notice a spike in login attempts or repeated authentication failures. Eventually, one of those attempts succeeds, and a valid token is issued. From there, activity stabilizes. Requests continue without further login attempts, making it look like normal usage.
How to trace it:
Correlate login events with token activity and follow what happens after a successful authentication.
user_id: 78421
01:58:19 - Failed login from IP 185.220.101.12
01:58:27 - Failed login from IP 185.220.101.12
01:59:03 - Login success from IP 45.22.11.9
01:59:05 - Token issued: eyJhbGci...abc
02:01:11 - Request from IP 103.21.45.12 — /api/profile
02:01:18 - Request from IP 185.93.22.67 — /api/orders
02:01:26 - Request from IP 103.21.45.12 — /api/billing
Here, the login succeeds from one IP, but the same token starts appearing across different IPs shortly after. There are no additional login events tied to this activity. That shift matters. The token is no longer tied to the session that created it.
What to do next:
Invalidate tokens issued during suspicious login activity. If multiple IPs are using the same token without re-authentication, treat it as compromised and block it at the gateway while you continue the investigation.
- Token Theft Vectors
You are seeing token usage that does not line up with user behavior, and there is no login event explaining it.
At this point, the question is not “what is the token doing,” but “how did someone else get it.” In most cases, this comes from how the token is handled outside your API. Tokens stored in localStorage or sessionStorage can be read by scripts. Browser extensions can access them. Third-party services may hold them longer than expected. In some cases, users grant access without realizing it.
How to trace it:
Start with the token and compare where it was issued versus where it is being used.
user_id: 91842
token_id: eyJhbGci...pL9
14:12:08 - Login success from IP 45.22.11.9 — Chrome (Windows)
14:12:10 - Token issued
14:18:33 - Request from IP 103.21.45.12 — Chrome (Windows) — /api/profile
14:19:02 - Request from IP 185.93.22.67 — Unknown client — /api/orders
14:19:11 - Request from IP 185.93.22.67 — Scripted agent — /api/export
The token was issued to a browser session from one IP. Shortly after, it appears from a different IP and a different client type. There is no login event tied to this shift. The token is being used outside the original session.
What to do next:
Treat the token as exposed. Revoke it immediately and review where it may have been accessible. Focus on client-side storage and any integrations handling that token.
Layer 3: Is the Token Even Legitimate (Integrity)
- JWT Tampering and Forgery
Requests are going through, but something feels off when you look at the token itself. The roles do not match the user; expiry values look unusually long, or some claims do not align with how your system issues them.
Nothing fails here. The token is accepted, and the request is completed as expected. If you only look at logs, this will not stand out. The structure looks fine, and the request flow does not break.
How to trace it:
Take a token being used in these requests and compare it against a token issued by your system.
Token observed in request:
role: admin
exp: 1912345678
iss: unknown-service
Token issued by your system:
role: user
exp: 1712345678
iss: auth.yourdomain.com
The observed token carries elevated privileges and a longer expiry than your system normally assigns. The issuer also does not match your authentication service.
This token was not generated through your normal issuance flow. If it is still being accepted, validation is not enforcing signature or issuer checks correctly.
What to do next:
Treat this as a forged token being accepted. Restrict access immediately and identify which services are accepting tokens without strict verification.
Layer 4: Why Did the System Accept It (Validation)
- Broken JWT Validation
Requests continue to succeed even when the token should not be accepted. Expired tokens may still work. Tokens from other systems may be accepted. Issuer or audience checks may not be enforced consistently. These issues may not stand out immediately. Over time, they change what your system accepts as valid.
How to trace it:
Take one of the tokens being used and validate it outside your application.
token_id: eyJhbGci...kL2
Decoded payload:
exp: 1712345678 (expired)
iss: external-auth-service
aud: unknown-service
Observed request:
GET /api/internal/data → 200 OK
The token is expired and issued by a different system. It should not be accepted. The fact that the request succeeds means validation checks are not being enforced consistently.
What to do next:
Standardize validation across all services. Enforce strict checks for signature, expiry, issuer, and audience before allowing access.
- Algorithm Confusion (alg:none / RS256 to HS256 Swap)
Everything looks normal from the outside. Requests are authenticated, tokens are accepted, and no validation errors are surfacing. But the tokens being accepted may not have been issued by your system at all.
This happens when validation logic trusts the algorithm declared in the token header rather than enforcing a fixed algorithm server-side. An attacker can set the algorithm to none, stripping the signature entirely, and the token still gets accepted. In another variant, a token signed with your public key using HS256 gets accepted by a system expecting RS256, because the public key is being used as the HMAC secret.
From logs alone, this is invisible. The token structure looks valid, requests succeed, and there are nothing to chase.
How to trace it:
Decode the header of a suspicious token and check the algorithm field:
Decoded header (legitimate):
{
"alg": "RS256",
"typ": "JWT"
}
Decoded header (tampered):
{
"alg": "none",
"typ": "JWT"
}
or
{
"alg": "HS256",
"typ": "JWT"
}
If your system is accepting tokens with alg:none or an unexpected algorithm, your validation logic is not enforcing a fixed algorithm. To confirm, take the suspicious token and run it through your validation stack independently. If it passes without a valid RS256 signature, you have confirmed the vulnerability.
What to do next: Enforce a fixed algorithm server-side and reject any token that declares a different one in its header. This should be a hard check in your validation middleware, not a conditional one.
Layer 5: How Long Has This Been Happening (Persistence)
- Token Lifetime and Refresh Abuse
Access continues over an extended period without re-authentication.
Tokens may remain active longer than expected, or refresh tokens may be reused after rotation. This allows access to persist without interruption.
How to trace it:
Track how a single refresh token is used over time and correlate it with new access tokens being issued.
user_id: 55218
refresh_token: rft_89xk...21
09:58:11 - Login success from IP 45.22.11.9
09:58:13 - Refresh token issued: rft_89xk...21
10:30:02 - Refresh used from IP 45.22.11.9 → new access token issued
10:30:04 - Access token used — /api/profile
10:45:17 - Refresh used again from IP 185.93.22.67 → new access token issued
10:45:19 - Access token used — /api/orders
The same refresh token is used again after it has already been exchanged. The second use also comes from a different IP. A refresh token should not be valid after it has been used once. Reuse means it has been copied or intercepted.
What to do next:
Revoke the entire token chain associated with that refresh token. If refresh tokens are reusable in your system, flag this immediately and restrict further token issuance while you investigate.
Signal to Investigation: A Quick Reference for Active Diagnosis
After running through the diagnostic sections, use this table to map what you are currently observing to where your investigation should focus first. If multiple rows apply simultaneously, do not investigate them in isolation, overlapping signals usually point to a single compromised token being used across contexts. Start with token revocation and work backwards from there.
| What You Are Seeing | What It Suggests | Where to Check First |
|---|---|---|
| Same token across multiple IPs or regions | Token replay or session hijacking | Access logs for IP distribution and session overlap |
| Token activity without user interaction | Automated use or token leakage | User activity timelines vs API request logs |
| Token used from different devices or user agents | Reuse outside original client | Device fingerprinting and User-Agent history |
| Sudden increase in requests from a single token | Scripted usage or abuse at scale | Rate patterns in API gateway or traffic logs |
| Token accessing endpoints outside its assigned role | Scope or claims abuse | Token payload vs endpoint authorization middleware |
| Token accepted with unexpected algorithm or no signature | Algorithm confusion or validation bypass | Token header inspection and validation middleware configuration |
| Expired or cross-system token still being accepted | Broken JWT validation | Expiry, issuer, and audience checks in validation logic |
| Refresh token reused after rotation | Token duplication or interception | Authentication service logs and refresh token workflows |
| Token continues after logout or extended inactivity | Token not revoked or persisting beyond session | Session handling and token revocation logic |
| Token active across multiple services simultaneously | Token spread or lateral reuse | Service-level logs and cross-API correlation |
Get Live Help Now