Web App 4 min read

JWT and OAuth: the seven authentication mistakes that open the door without breaking the crypto

It's almost never the cryptography that fails — it's how the token is validated, where it's stored and what the OAuth flow trusts. The seven broken-authentication patterns we find most, what to test and how to fix them.

Also in PTESPT-BR
JWT and OAuth: the seven authentication mistakes that open the door without breaking the crypto

The attack doesn’t pick the lock — it uses the back door

When JWT or OAuth authentication falls in a pentest, it is almost never because we broke AES or RSA. It is because the token validation has a hole, the flow trusts a parameter the attacker controls, or the token lives somewhere it can be stolen. Broken authentication is item A07 of the OWASP Top 10, and it is where a single flaw becomes access to any user’s account.

Below, the seven patterns we find most — what they are, how we test them, and what fixes them.

1. alg: none and variants

A JWT states how it should be verified in its own header (alg). Old or misconfigured libraries accept alg: none — an unsigned token — or fail to pin the expected algorithm. Test: switch alg to none, strip the signature, see if the backend accepts it. Fix: pin the algorithm on the server (allowlist); never read alg from the token to decide how to validate.

2. RS256 → HS256 confusion

The server uses RS256 (public/private key). The attacker changes the header to HS256 (symmetric) and signs the token using the public key — which is, by definition, public — as if it were the HMAC secret. Libraries that pick the verifier from the token’s alg fall for this. Fix: verifier strictly bound to the expected algorithm.

3. Weak or leaked HMAC secret

HS256 with a secret of secret, changeme, the company name, or a secret leaked in a public repo. With the secret, the attacker forges any token — becomes admin in one line. Test: offline dictionary attack on the signature. Fix: high-entropy random secret, out of the code, rotatable.

4. Unvalidated claims

The signature checks out, but the backend does not validate exp (expiry), aud (audience) or iss (issuer). An expired token stays valid; a token issued for another service is accepted. Test: reuse an expired token, use a token from another environment/service. Fix: always validate exp, nbf, aud, iss; reject by default.

5. Loose redirect_uri in OAuth

The heart of many SSO account takeovers. If the authorization server matches redirect_uri by prefix or allows arbitrary subdomains/paths, the attacker diverts the code or token to a domain they control. Variations: an open redirect chained into the flow, missing state (login CSRF), PKCE not required for public clients. Test: manipulate redirect_uri, drop state, intercept the code. Fix: exact redirect_uri allowlist, mandatory state, PKCE for SPA and mobile.

6. Token in the wrong place

A JWT in localStorage is readable by any XSS — and then a single XSS becomes persistent session theft. Token in logs, in the URL (referer leaks), in a CDN cache. Fix: HttpOnly, Secure, SameSite cookies; never a session token in localStorage; never a token in a query string.

7. No revocation and eternal sessions

A JWT is stateless: once issued, it is valid until it expires. If exp is long and there is no revocation list or rotated refresh token, a stolen token works for hours or days, and changing the password does not log the attacker out. Fix: short exp + rotated, revocable refresh token; invalidate sessions on password change and logout.

Why scanners miss it

Almost all of these require manipulating the token and understanding the flow — two contexts, two accounts, a proxy intercepting the OAuth handshake. A scanner sees a login that works and moves on. This is manual testing, guided by the OWASP WSTG (authentication section) and OAuth 2.0 / OIDC best practice.

What to ask for in the pentest

Ask for explicit coverage of: alg manipulation, algorithm confusion, offline brute force of the secret, claim validation, the entire OAuth/OIDC flow (including redirect_uri, state, PKCE), token storage and session lifecycle. And ask for the chain to impact — "I forged an admin token" is worth more than "exp is not validated".

How Pentest Machine tests this

In web and API pentests we treat authentication as a first-class surface: JWT manipulation, full OAuth/OIDC flows, SSO, storage and session, with a reproducible PoC for every flaw and the path to account takeover when it exists. Executive + technical report and retest included. If you use SSO or issue JWTs to clients, this is the test that separates "looks secure" from "is secure".