← Back to blog
Blog Detail

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.

Trusteed Team
Trusteed Editorial
Written On
Sep 30, 2026
Category
CTEM
Read Time
13 min read
  • CTEM
  • Trusteed
  • JWT Security
  • API Security
  • Token Attacks
  • Attack Surface Management
  • Application Security
JWT Weaknesses and Token Attacks in Web/API Recon: Validation Gaps CTEM Teams Should Measure

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), unchecked iss/aud/exp, injectable kid, and attacker-controlled jku/x5u/jwk headers.
  • 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, kid injection.
  • Claim validation gaps — unenforced aud, iss, exp, nbf, or typ; role and tenant claims trusted from a token minted for a different audience.
  • Key management gaps — embedded jwk, remote jku/x5u fetch, 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, Referer headers, 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

Dark Trusteed insight card titled 'The JWT Validation Gap'. Left column shows the verified path: fixed alg allowlist, issuer-pinned JWKS, pinned aud/iss, and claims checked after signature verification. Right column shows three attacker paths, each labelled with the control that blocks it: alg:none replay blocked by an explicit alg allowlist, RS256 to HS256 key-confusion blocked by binding alg to key type, and an attacker-hosted jku JWKS blocked by JWKS allowlisting and issuer pinning. A lower strip lists the CTEM measurements — inventory, exposure and proof — above the Trusteed Threat Research footer.

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, kid values, and whether retired keys linger.
  • Decode a legitimately issued token and record alg, kid, iss, aud, exp - iat, and whether a jti exists.
  • Test the verifier, not the issuer: alg: none, algorithm swap, kid traversal, removed exp, swapped aud, 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

Dark Trusteed telemetry card titled The JWT Validation Gap: Signals Worth an Alarm. It shows decoded token metadata (alg RS256 with HS256 also seen, kid present in 96.1%, three distinct issuers, 1.2% audience mismatch, median exp minus iat of 42 minutes, jti present in 88%), anomaly panels for algorithm misuse and token lifetime buckets, kid and jku hygiene hits, same-jti replay across ASNs, issuance spikes by ASN, and a should_alarm gate that promotes 37 alerts from 1.24M decoded tokens into the SOC queue. Footer carries the Trusteed Threat Research mark.

Good telemetry starts with decoding token metadata at the edge — never the raw token.

  • Auth-aware gateway logs: alg, kid, iss, aud, exp - iat, and jti presence 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*.
  • kid and key-URL hygiene: kid values containing path separators, quotes, SQL metacharacters, or URLs; jku/x5u hosts outside an allowlist.
  • Issuer and audience drift: tokens from an unexpected iss, or presented to a service whose aud the issuer never intended.
  • Lifetime distribution: share of tokens with exp - iat above policy, and count of tokens issued without jti — meaning no revocation handle.
  • Replay indicators: the same jti from 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 sub values (successful credential stuffing), or many issuances for one sub from 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

  1. 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.
  2. Validate the full claim set. Enforce exp, nbf, iat, iss, aud, and typ with a small clock skew. Treat aud as required and pinned, not optional.
  3. Never trust jku, x5u, or jwk from the token. Resolve keys only from a configured, allowlisted JWKS URL, and apply egress controls so jku can't be weaponized as SSRF.
  4. Treat kid as 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.
  5. 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.
  6. Short TTL plus real revocation. Access tokens in the 5–15 minute range, refresh rotation with reuse detection, a jti denylist covering the remaining window, and logout that invalidates server-side state.
  7. 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.
  8. Keep tokens where XSS can't reach them. HttpOnly, Secure, SameSite cookies for browser flows; no localStorage. If a token must live in JavaScript, pair it with a strict CSP and aggressive lifetime limits.
  9. Get tokens out of URLs and logs. Use Authorization headers, redact token patterns in logging pipelines, and block token-shaped query parameters at the edge.
  10. Test continuously and report the number. Add JWT cases to CI (algorithm swap, kid traversal, expired replay, audience swap) and include auth endpoints in external attack surface scanning. Then track the percentage of token-consuming routes with enforced alg, aud, and TTL policy — that single metric is a credible exposure KPI for engineering leadership.

How Trusteed CTEM helps

Dark Trusteed CTEM workflow card: attack surface discovery feeds an API surface worker and deep DAST, then exploitability enrichment with catalog CVE data, EPSS, CISA KEV and exploit references, then a validation gate filtering to actionable findings, ending in the operator workspace and reporting views.

  • 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

Join Our Newsletter

Trusteed keeps you informed: emerging risks, platform updates, and practical guides for faster defense.

JWT Weaknesses in API Recon: CTEM Validation Gaps