JWT Weaknesses and Token Attacks in Web/API Recon: Validation Gaps CTEM Teams Should Measure
JWT weaknesses — alg:none, algorithm confusion, forged claims, and leaked bearer tokens — are measurable API exposure, not just a code smell. Learn how CTEM teams inventory token-issuing endpoints, detect real validation gaps, prioritize the ones attackers exploit, and prove risk reduction with Trusteed CTEM.

JWT Weaknesses and Token Attacks in Web/API Recon: Validation Gaps CTEM Teams Should Measure
TL;DR
- JWTs are self-describing bearer tokens. The signature is the only thing separating a legitimate user from a forged identity claim — and in most real-world findings, the cryptography was never the problem.
- The exploitable issues are validation gaps:
alg: none, algorithm confusion (RS256 → HS256), uncheckediss/aud/exp, injectablekid, and attacker-controlledjku/x5u/jwkheaders. - Tokens also leak — into URLs, access logs, JS bundles, mobile binaries, and public repos — which makes token security an attack surface problem, not just a code review item.
- JWT exposure is measurable: endpoint coverage, algorithm distribution, token lifetime spread, revocation handling, key hygiene, and replay anomalies.
- Trusteed CTEM continuously inventories the endpoints that issue and accept tokens, tests the API surface they protect, and routes only validated, exploitability-backed findings to the SOC.
What are JWT weaknesses and token attacks?
A JSON Web Token (RFC 7519) is a compact, self-describing credential: base64url(header).base64url(payload).base64url(signature). The header declares how the token is signed (alg), which key to use (kid), and occasionally where to fetch a key (jku, x5u, jwk). The payload carries claims — iss, sub, aud, exp, nbf, iat, jti — plus application roles and tenant identifiers.
A JWT weakness is any condition where a relying party accepts a token it should reject, or grants a valid token more scope or lifetime than intended. Token attacks are the techniques used to forge, tamper with, replay, confuse, or steal those tokens.
In practice, findings cluster into five families:
- Algorithm and format confusion —
alg: none, RS256 → HS256 confusion, brute-forceable HMAC secrets,kidinjection. - Claim validation gaps — unenforced
aud,iss,exp,nbf, ortyp; role and tenant claims trusted from a token minted for a different audience. - Key management gaps — embedded
jwk, remotejku/x5ufetch, stale JWKS caches, keys shared across tenants, no rotation. - Lifecycle gaps — long TTLs, no revocation path, refresh-token reuse without detection, no sender constraint (no DPoP or mTLS binding).
- Leakage — tokens in query strings,
Refererheaders, logs, bundles, mobile binaries, and Git history.
Why it matters now
APIs are the product now, and token-based auth is the default control plane for them. That means one validation gap in one service isn't a single-account bug — it's an authorization bypass with a repeatable exploit path. If a relying party skips aud, a token minted for a low-value reporting service is accepted by the admin API. If it skips exp, a leaked token never dies. If it selects its verification algorithm from the token header, the attacker chooses the cryptography.
Two structural shifts make this worse. Microservices and third-party identity providers multiply the number of relying parties that must independently validate the same token, so drift is inevitable. Meanwhile, single-page apps and mobile clients push tokens out of HttpOnly cookies into places XSS and device compromise can reach.
The business impact is familiar: account takeover at scale, cross-tenant data access, privilege escalation to admin, fraud, and breach-notification obligations. What makes JWT weaknesses distinct is that they rarely have a CVE. There is no CVE for "your gateway accepts alg: none" — so vulnerability management programs don't see it, patch cycles don't cover it, and the gap survives quarter after quarter. That is precisely the gap continuous exposure management exists to close.
How JWT attacks work

Most JWT attacks are not cryptanalysis. They are attempts to make the verifier do something the developer didn't intend.
Algorithm downgrade (alg: none). Historically, some libraries honored a header of alg: none and accepted a token with an empty signature. Mainstream libraries reject it today, but hand-rolled parsers, legacy gateway rules, and decode-then-trust middleware still appear in real assessments. The test is free: strip the signature, set the algorithm, replay.
Algorithm confusion (RS256 → HS256). A service signs with an asymmetric private key and publishes the public key at a JWKS endpoint. If verification picks the primitive from the token's alg header instead of a configured value, an attacker signs an HS256 token using the public key as the HMAC secret — and the service verifies it happily, because that is exactly the key it uses to check the HMAC. Libraries with a single verify(token, key) signature are the classic culprit.
Weak HMAC secrets. HS256 with a secret like secret, changeme, or the product name is offline-brute-forceable with hashcat or jwt_tool wordlists. The token itself is the oracle, so there's no rate limit, no lockout, and no log entry.
kid injection. The kid header is frequently used to look up a key by filename, database row, or cache key. Path traversal can select an empty file, producing a "signed" HMAC token with an empty secret. SQL or command injection in that lookup escalates from forgery to worse.
jku / x5u / jwk injection. If the verifier fetches a key set from a URL supplied in the token header without an allowlist, the attacker hosts their own JWKS, signs with their own private key, and the service trusts it. An embedded jwk skips even that step. Unvalidated jku also becomes SSRF: the service fetches whatever URL the attacker supplies, including internal metadata endpoints.
Claim forgery and scope confusion. Tokens are often decoded but incompletely validated. exp ignored means immortal sessions; aud unchecked means audience confusion between services; iss unpinned means any tenant's issuer is accepted; sub or role trusted across audiences means horizontal and vertical escalation. typ confusion lets an ID token be replayed as an access token.
Replay and lifecycle abuse. Stateless tokens can't be revoked without a jti denylist or a short TTL. Refresh tokens with rotation gaps provide durable access even after a user "logs out" — because logout only cleared the client.
Leakage channels. ?token= in a URL lands in access logs, reverse proxies, browser history, and Referer headers. Tokens committed in JS bundles, source maps, mobile APKs, or public repos are reconnaissance gold — no exploitation skill required.
A practical recon loop for token endpoints:
- Enumerate issuance and discovery endpoints:
/oauth/token,/connect/token,/realms/{realm}/protocol/openid-connect/*,/.well-known/openid-configuration,/oauth/jwks,/.well-known/jwks.json. - Fetch the JWKS and note key types,
kidvalues, and whether retired keys linger. - Decode a legitimately issued token and record
alg,kid,iss,aud,exp - iat, and whether ajtiexists. - Test the verifier, not the issuer:
alg: none, algorithm swap,kidtraversal, removedexp, swappedaud, cross-issuer replay, post-logout replay. - Stay in scope and rate-limit. These tests are cheap, but they belong inside an authorized test plan with logging — not an unbounded spray.
Detection and visibility

Good telemetry starts with decoding token metadata at the edge — never the raw token.
- Auth-aware gateway logs:
alg,kid,iss,aud,exp - iat, andjtipresence on every authenticated request, correlated to route and tenant. - Algorithm anomaly alerts: any
alg: none; any algorithm that differs from the value configured for that route; any HS* token presented to a service that should only accept RS*/ES*. kidand key-URL hygiene:kidvalues containing path separators, quotes, SQL metacharacters, or URLs;jku/x5uhosts outside an allowlist.- Issuer and audience drift: tokens from an unexpected
iss, or presented to a service whoseaudthe issuer never intended. - Lifetime distribution: share of tokens with
exp - iatabove policy, and count of tokens issued withoutjti— meaning no revocation handle. - Replay indicators: the same
jtifrom different ASNs or device fingerprints in a short window; token use after logout; refresh-token reuse. - Issuance anomalies: one IP or ASN minting tokens for many distinct
subvalues (successful credential stuffing), or many issuances for onesubfrom many ASNs. - Leakage telemetry: secret scanning across repos and bundles, edge rules that flag token-shaped query parameters, and log-pipeline redaction coverage.
- Relying-party inventory: the list of services that accept tokens. You cannot measure validation coverage across systems you haven't enumerated — and that inventory is the part point tools rarely deliver.
Reduce risk: best practices
- Pin the algorithm server-side. Configure accepted algorithms per route and never derive the verification primitive from the token header. Reject
none, and reject symmetric algorithms anywhere public-key verification is expected. - Validate the full claim set. Enforce
exp,nbf,iat,iss,aud, andtypwith a small clock skew. Treataudas required and pinned, not optional. - Never trust
jku,x5u, orjwkfrom the token. Resolve keys only from a configured, allowlisted JWKS URL, and apply egress controls sojkucan't be weaponized as SSRF. - Treat
kidas hostile input. Map it to a key through an allowlist or enum — never a filesystem path, a SQL query, or a cache key built from user input. - Fix key hygiene. Use CSPRNG secrets of at least 256 bits for HS256, store them in a secrets manager, never reuse a signing key across tenants or services, and rotate with a verification overlap window.
- Short TTL plus real revocation. Access tokens in the 5–15 minute range, refresh rotation with reuse detection, a
jtidenylist covering the remaining window, and logout that invalidates server-side state. - Bind tokens to clients where it counts. DPoP or mTLS-bound tokens (RFC 9449 / RFC 8705) turn a stolen bearer token into a useless one on high-value APIs.
- Keep tokens where XSS can't reach them. HttpOnly,
Secure,SameSitecookies for browser flows; nolocalStorage. If a token must live in JavaScript, pair it with a strict CSP and aggressive lifetime limits. - Get tokens out of URLs and logs. Use
Authorizationheaders, redact token patterns in logging pipelines, and block token-shaped query parameters at the edge. - Test continuously and report the number. Add JWT cases to CI (algorithm swap,
kidtraversal, expired replay, audience swap) and include auth endpoints in external attack surface scanning. Then track the percentage of token-consuming routes with enforcedalg,aud, and TTL policy — that single metric is a credible exposure KPI for engineering leadership.
How Trusteed CTEM helps

- Inventory first, including the endpoints you forgot. Trusteed CTEM discovers external and internal attack surface across domains, IPs, services, and technologies using passive and active discovery with ongoing scan plans, so token issuers, JWKS paths, and API gateways land in the asset graph instead of a spreadsheet. See trusteed.io.
- Dedicated API surface testing. A purpose-built API worker tests the API plane where JWT issues actually live, complementing generic DAST coverage.
- Deep DAST for critical applications. Where token handling sits in application code, a deeper web application worker extends coverage beyond template-based checks.
- Exploitability context on every finding. Scanner detections are enriched with catalog CVE data, EPSS and KEV context, and exploit references where available, so outdated auth libraries and identity gateways rank above cosmetic findings.
- A validation gate in front of the SOC. Not every scanner hit becomes an alarm. Trusteed validates exploitability and business context so dashboards and analyst queues focus on actionable risk (
should_alarm) instead of raw output volume. - Reporting and framework views. Because login and session weaknesses rarely carry a CVE, measurable auth coverage and trend reporting matters for both engineering and compliance conversations.
Trusteed CTEM vs point tools
JWT linters, Burp extensions, and jwt_tool are excellent at proving a specific endpoint is broken. They are not a program.
| Capability | Typical point tool (JWT linter / single-purpose scanner) | Trusteed CTEM |
|---|---|---|
| Discovery | You supply the URL and a sample token | Continuous discovery of domains, IPs, services, and technologies, with ongoing scan plans |
| Test depth | One endpoint, one technique per run | API surface worker plus deep DAST, alongside network, web, SSL/TLS, and mail/DNS posture |
| Threat context | Pass/fail or CVSS only | Catalog CVE data with EPSS/KEV context and exploit references where available |
| Noise handling | Every hit reported to whoever ran it | Validation gate scores exploitability and business context so only actionable findings alarm |
| Continuity | Point-in-time; drift between runs | Continuous scan plans that re-test as the surface changes |
| Workflow and reporting | Raw output triaged by hand | Operator workspace at app.trusteed.io plus framework-oriented and customer reporting |
FAQ
Are JWTs inherently insecure? No. They are a well-specified format with known failure modes. JWT estates break when validation is partial or key handling is careless — both are correctable engineering problems, not reasons to abandon the pattern.
Can attackers actually brute-force an HS256 secret? Yes, whenever the secret isn't random. Brute-forcing runs offline against the token itself — no rate limit, no lockout, no log. Short dictionary-style secrets fall in seconds to hours on commodity hardware; a 256-bit CSPRNG secret does not.
How do I check whether my API validates tokens correctly?
Run a binary test set against each relying party: replay with alg: none; swap RS256 for HS256 signed with the public key; tamper with kid; replay an expired token; replay a token whose aud doesn't include that service; replay a token from a different iss; replay a token after logout. Each test either passes or fails.
Is alg: none still a real issue?
Mainstream libraries have rejected it for years, but custom middleware, in-house parsers, and legacy gateway rules still honor it. It costs nothing to test, and it is a full authentication bypass when it works.
Should we stop using JWTs and go back to server sessions? Choose deliberately. Session cookies are simpler to revoke and fit browser-only applications well. Stateless tokens fit distributed APIs and mobile clients — provided you accept the revocation trade-off and mitigate it with short TTLs, rotation, and denylisting. The failure mode is picking one without documenting the trade-off.
How does CTEM differ from running a scanner? A scanner produces a signal at a point in time. CTEM is the workflow around it: continuously discover the attack surface (including every service that accepts a token), test it, validate which findings are genuinely exploitable in your context, prioritize them against threat intelligence, and re-test after remediation. JWT weaknesses show why the workflow matters — most have no CVE, so nothing flags them unless you own the inventory.
How often should token validation be tested? On every auth service and gateway deploy, plus continuously from the outside. Validation drifts the moment someone adds a relying party or relaxes a claim check, and that drift is invisible without scheduled testing.
Do short-lived tokens remove the need for revocation?
They shrink the window; they don't remove the need. If access tokens live 15 minutes, a jti denylist covering that window plus refresh-token reuse detection handles the residual risk. Multi-day tokens with no revocation path are the opposite design.
Related resources
- Trusteed CTEM platform — continuous threat exposure management for external and internal attack surface.
- Trusteed tenant app — asset inventory, findings, and validated SOC queues.
- Trusteed blog — CTEM playbooks, CVE analysis, and API attack surface research.
- RFC 8725: JSON Web Token Best Current Practices
- OWASP WSTG — Testing JSON Web Tokens
- OWASP JSON Web Token Cheat Sheet
- NIST SP 800-63B: Digital Identity Guidelines — Authentication
- CISA Secure by Design