Skip to content
Back to Blog
·9 min read·technology

JWT Attacks: None Algorithm and Key Confusion Explained

How attackers forge JWTs via alg=none, RS256-HS256 key confusion, weak HMAC secrets, and kid injection — and how Indian API teams verify tokens correctly.

BR

Bachao.AI Research Team

Cybersecurity Research

Scan Your Attack Surface

Security exposure this creates

Unpatched vulnerabilities in your tech stack are the #1 entry point for breaches targeting Indian businesses. Here's what to watch.

A JSON Web Token proves who a user is, but only if your server verifies it correctly. The most damaging JWT attacks — the alg=none bypass, RS256-to-HS256 key confusion, weak HMAC secret brute-forcing, and kid/jwk header injection — all exploit the same root cause: the server trusting attacker-controlled header fields instead of enforcing its own signing algorithm and key. Fix that one assumption and most JWT attack classes disappear.

For Indian API teams shipping fast on Node, Spring, or Django, JWTs are the default session mechanism — and misconfigured verification is one of the most common findings in API penetration tests today.

How JWT Attacks Work — and Where Trust Breaks

A JWT has three Base64URL-encoded parts separated by dots: header, payload, signature. The header declares the signing algorithm (alg) and, in many implementations, an optional kid (key ID) or jwk/jku (embedded or referenced public key). The payload carries claims like sub, exp, iss, aud. The signature is computed over the header and payload using a server-side secret or private key.

The critical design flaw many libraries inherited: the header is attacker-controlled. If your verification code reads alg from the incoming token and dynamically picks a verification method based on it, an attacker who can edit the header before you verify it effectively picks how you verify their forged token. That single mistake underlies almost every attack below.

Attack 1: The alg=none Bypass

The JWT spec defines none as a legitimate (unsecured) algorithm for cases where integrity is handled elsewhere. Some libraries, especially older or loosely configured ones, will accept a token with "alg": "none" and an empty signature as valid — because "no algorithm" technically means "no verification needed."

An attacker decodes a legitimate token, sets alg to none, edits the payload (e.g., "role": "admin"), removes the signature entirely, and re-encodes it. If the server's verify call does not explicitly reject none, the forged token is accepted.

🚨
DANGER
Any JWT library configuration that lets the token itself declare its verification algorithm is exploitable. Always pin the expected algorithm(s) server-side and reject anything else before touching the payload.

Attack 2: RS256 to HS256 Key Confusion

This is the most consequential JWT vulnerability because it turns a public key into a forgery tool. RS256 is asymmetric: the server signs with a private key and verifies with a public key that can be shared freely (often exposed via a /jwks.json endpoint or embedded in a mobile app). HS256 is symmetric: the same secret both signs and verifies.

Some JWT libraries expose a single generic verify(token, key) function that does not enforce which algorithm the key is meant for. If an attacker knows the server uses RS256 and can obtain the public key, they can:

  1. Take the public key (freely available by design)
  2. Craft a token with "alg": "HS256"
  3. Sign it using the public key as the HMAC secret
  4. Send it to the server
If the server's verification code does jwt.verify(token, publicKey) without pinning algorithms: ['RS256'], it will use the attacker-chosen HS256 path with the public key as the HMAC secret — a secret the attacker already knows because it was never secret. The result: a validly "signed" token with any claims the attacker wants, including elevated privileges.

Know your vulnerabilities before attackers do

Run a free VAPT scan — takes 5 minutes, no signup required.

Book Your Free Scan

Attack 3: Weak HMAC Secrets

When a team does use HS256 correctly, the security of every issued token still depends entirely on the strength of one shared secret. Weak secrets — short strings, dictionary words, default values left over from a tutorial or a leaked .env file — are brute-forceable offline once an attacker has a single valid token. Tools built for this (hashcat, John the Ripper JWT modules) can test millions of candidate secrets per second against the token's signature with no rate limiting possible, because the attack happens entirely offline.

🛡️
SECURITY
HMAC secrets used for JWT signing should be generated with a cryptographically secure random source, be at least 256 bits (32 bytes) for HS256, and never be reused across environments (dev, staging, production) or across services.

Attack 4: kid Injection and SQL/Path Traversal via Header

The kid (Key ID) header tells the verifier which key to use when multiple signing keys are in rotation — useful, but dangerous if the server trusts it blindly. If the backend uses the kid value to build a file path (/keys/{kid}.pem) or a database lookup (SELECT key FROM keys WHERE id = '{kid}') without sanitizing it, an attacker can inject:

    1. Path traversal: kid: ../../../../dev/null to point the verifier at an empty or predictable file, which some libraries then treat as a zero-length key
    2. SQL injection: kid: ' OR '1'='1 to manipulate the key-lookup query
    3. Command injection: in rare cases where kid reaches a shell call
Any of these can trick the server into verifying against a key of the attacker's choosing.

Attack 5: jwk / jku Header Abuse

Some JWT implementations support an embedded public key (jwk) or a URL to a key set (jku) directly in the token header — intended for federated scenarios. If the server fetches and trusts whatever key the token itself supplies:

    1. With jwk, the attacker embeds their own key pair in the header, signs the forged token with their own private key, and the server dutifully verifies it against the attacker-supplied public key. Signature check passes; the token is entirely attacker-controlled.
    2. With jku, the attacker hosts a malicious JWK Set on a server they control and points the header at it. If the server does not restrict jku to an allow-listed, trusted domain, it will fetch and trust an attacker's keys.

Attack 6: Missing Expiry, Audience, and Issuer Validation

Even a correctly signed, unforgeable token can be misused if the server checks the signature but skips claim validation. Common gaps:

    1. No exp check — expired tokens (or tokens with no expiry at all) remain valid indefinitely, defeating logout and session rotation.
    2. No aud check — a token issued for one service (e.g., a mobile app) is accepted by an unrelated internal service, enabling cross-service replay.
    3. No iss check — a token from a different trust domain or environment (staging vs. production) is accepted as legitimate.
These are not exotic bugs — they are simply verification steps that developers assume the JWT library handles automatically. Most libraries validate the signature by default but require the developer to explicitly request exp, aud, and iss checks. NIST's Digital Identity Guidelines (SP 800-63B) treat authenticator and session verification as a distinct control from identity proofing for exactly this reason — a valid signature only proves integrity, not that the session is still authorized.
graph TD A[Attacker captures JWT] --> B[Tamper alg or key header] B --> C[Forge signature] C --> D{Server verifies} D -->|Trusts header| E[Auth bypass] D -->|Pins alg and key| F[Token rejected] E --> G[Account takeover] F --> H[Harden verification] style A fill:#5f1e1e,stroke:#EF4444,color:#e2e8f0 style B fill:#5f1e1e,stroke:#EF4444,color:#e2e8f0 style C fill:#5f1e1e,stroke:#EF4444,color:#e2e8f0 style D fill:#1e3a5f,stroke:#3B82F6,color:#e2e8f0 style E fill:#5f1e1e,stroke:#EF4444,color:#e2e8f0 style F fill:#1e3d2f,stroke:#10B981,color:#e2e8f0 style G fill:#5f1e1e,stroke:#EF4444,color:#e2e8f0 style H fill:#1e3d2f,stroke:#10B981,color:#e2e8f0

Defence: Verifying JWTs Correctly

The fix for nearly every attack above is the same principle applied consistently: never let the token tell the server how to verify itself.

ControlWhy it mattersImplementation note
Pin the algorithm server-sideStops alg=none and RS256-to-HS256 confusionPass algorithms: ['RS256'] explicitly to the verify call; never derive it from the token header
Use separate key material per algorithmPrevents public keys doubling as HMAC secretsNever let the same value serve as both an RSA public key and an HMAC secret
Strong, rotated HMAC secretsDefeats offline brute-force256-bit minimum, generated with a CSPRNG, rotated on a schedule, unique per environment
Validate kid against an allow-listStops path traversal / injection via headerLook up kid in a fixed in-memory map, never in a raw file path or unsanitized query
Ignore or allow-list jwk/jkuStops attacker-supplied keysReject embedded jwk outright unless required; restrict jku to a hardcoded trusted domain over HTTPS
Enforce exp, aud, issCloses replay and cross-service misuseExplicitly set audience, issuer, and clockTolerance options in the verify call
Short-lived access tokens + refresh flowLimits blast radius of any forged or leaked tokenMinutes, not days, for access tokens
💡
TIP
Treat JWT verification configuration as security-critical code, not boilerplate. Review it the same way you would review an authentication middleware — because that is exactly what it is.

Testing Your Own Implementation

Before an attacker finds these issues, an API-focused penetration test should specifically attempt: forging an alg=none token, re-signing a captured token with the public key under HS256, brute-forcing the HMAC secret offline, injecting path-traversal or SQL payloads via kid, and submitting a self-signed jwk header. Automated API scanning combined with manual verification-logic review during a broader free VAPT scan catches this class of bug far more reliably than a code read-through, since the flaw is in runtime verification behaviour, not obviously wrong-looking code. Credential and token-based attacks remain the dominant initial access route into breached applications, per the Verizon Data Breach Investigations Report — which is exactly the trust boundary JWT verification is meant to protect.

22%Breaches that began with compromised credentials, the same trust gap forged JWTs exploit (Verizon DBIR 2025)
88%Basic web application attacks involving stolen or forged credentials (Verizon DBIR 2025)
pie title Illustrative JWT Vulnerability Mix in API Pentests "Missing signature or claim validation" : 34 "Weak or hardcoded secrets" : 26 "Algorithm confusion or alg=none" : 18 "Header injection kid or jwk" : 14 "No expiry or replay protection" : 8
🎯Key Takeaway
Every JWT attack in this article exploits the same mistake: trusting a header field the attacker controls to decide how the server verifies the token. Pin your algorithm, separate your key material by algorithm type, validate every claim explicitly, and never let a token pick its own verification path.
⚠️
WARNING
A JWT library upgrade or migration is a common moment for these bugs to reappear — new defaults, new option names, or a copy-pasted example from documentation can silently reintroduce alg confusion. Re-test verification logic after every auth-library change.

Building This Into Your Development Process

For teams under India's DPDP Act 2023, an authentication bypass that exposes personal data isn't just a security incident — it is a reportable data breach with compliance consequences. Baking JWT verification checks into code review checklists, CI-based static analysis, and periodic penetration testing (ideally with a CERT-In empanelled partner for regulated engagements) closes the gap between "the library probably handles this" and "we verified it does." Bachao.AI, built by Dhisattva AI Pvt Ltd, runs automated and manual API testing designed to catch exactly this class of authentication-logic flaw before it ships. For broader regulatory context on why auth flaws matter beyond the technical fix, see the Bachao.AI blog and our guide on DPDP compliance.

Frequently Asked Questions

What is the alg=none JWT attack?
It exploits JWT libraries that accept a token whose header declares "alg": "none" with an empty signature as valid, letting an attacker forge any payload without knowing any secret. The fix is to explicitly reject none and pin the expected algorithm during verification.
How does RS256 to HS256 key confusion work?
An attacker takes the server's public RS256 verification key, which is intentionally shareable, and uses it as the HMAC secret to sign a token with alg set to HS256. If the server's verify function doesn't enforce which algorithm the key belongs to, it accepts the forged token.
Can a weak JWT secret really be brute-forced?
Yes. Once an attacker has one valid token, cracking the HMAC secret is an offline operation with no rate limiting possible, and short or dictionary-based secrets can fall within hours using standard cracking tools. A 256-bit random secret is not practically brute-forceable.
Why is the kid header dangerous?
If server code uses the kid value from the token header to build a file path or database query without sanitizing it, an attacker can inject path traversal or SQL payloads to redirect verification to a key of their choosing.
What claims should every JWT verification check besides the signature?
At minimum, expiry (exp), audience (aud), and issuer (iss). Signature validity alone only proves the token wasn't tampered with — it does not prove the token is still valid, intended for this service, or issued by a trusted source.
Is JWT inherently insecure?
No. JWT is a sound format when verification is implemented correctly — pinned algorithm, strong keys, and full claim validation. Nearly all real-world JWT breaches trace back to implementation shortcuts, not a flaw in the standard itself.
BR

Bachao.AI Research Team

Cybersecurity Research

AI-powered security research and threat intelligence from the Bachao.AI team. Covering the latest vulnerabilities, CVEs, and cybersecurity developments affecting Indian businesses.

Get cybersecurity insights for Indian SMBs

Weekly vulnerability alerts, DPDP compliance tips, and security guides. No spam — unsubscribe anytime.

We respect your privacy. Your email is never shared.

Find out if you're exposed to this class of threat

Free automated scan — risk score in under 2 hours. No credit card required.

Scan Your Attack Surface
Find your vulnerabilitiesStart free scan →