SoftwareTestPilot
Security TestingPublished: 11 min read

Top 10 JWT Security Vulnerabilities Every QA Should Test in 2026

The 10 JWT attacks QA teams miss: alg=none, key confusion, jku/kid injection, weak secrets, algorithm downgrade, and more — with test payloads and how to detect each one.

Avinash K
Founder & QA Engineer at SoftwareTestPilot
Share:XLinkedInWhatsApp
Top JWT security vulnerabilities OWASP checklist
Top JWT security vulnerabilities OWASP checklist

2026-07-17 · By Avinash K

JWT is easy to implement wrong. OWASP's API Security Top 10 lists broken authentication as #2, and JWT bugs cause most of it. Here are the ten attacks your QA suite should probe every release — with the exact payload to send and what a passing test looks like.

1. alg=none acceptance

Attacker changes the header to {"alg":"none"}, empties the signature, and the server accepts it. Test: forge a token with alg:none and hit any protected endpoint. Expect 401. If you get 200, the library is not pinning algorithms.

2. HS/RS algorithm confusion

Server expects RS256 but code calls verify(token, publicKey) without pinning. Attacker signs a token with HS256 using the RSA public key as the HMAC secret and it verifies. Test: download the public JWKS, sign HS256 with it, send. Expect 401.

3. Weak HMAC secret

Any HS256 token can be brute-forced offline if the secret is short. Test: run hashcat -m 16500 against a captured token with a common wordlist. Fail the build if it cracks in under 60s.

4. kid header path traversal / SQLi

The kid header often maps to a file path or DB lookup. kid: "../../dev/null" or kid: "x' UNION SELECT 'secret'--" can trick the server. Test: send both, expect 401 and no stack trace.

5. jku / x5u SSRF

jku tells the server where to fetch keys. If unrestricted, attacker points to attacker.com/jwks.json and signs with their own key. Test: set jku to an internal metadata URL (169.254.169.254). Expect 401 and no outbound request.

6. Missing exp / expired-token acceptance

Some servers skip expiry checks. Test: reuse a token with exp in the past. Expect 401. Then send a token with no exp at all — should also fail.

7. Sensitive claims in payload

Payload is readable. If you find password, ssn, credit_card, or full PII in a decoded token — that is a breach waiting to happen. Test: decode a fresh token and grep for banned claim names.

8. Audience / issuer bypass

A token issued for service A is accepted by service B. Test: mint a token for one microservice, replay it against another. Expect 401 unless multi-tenant is explicit.

9. Refresh-token replay

Refresh token used twice should invalidate the family. Test: use a refresh token, then use it again — expect logout of the whole session.

10. Log leakage

Full JWTs in server logs = credentials in your log aggregator. Test: grep production logs for eyJ (the base64 prefix of every JWT header).

Automate the audit

The JWT Debugger runs all 15 of these checks (10 above + 5 hygiene) on any token you paste — client-side. Copy the failing tokens straight into Postman or Playwright to add regression tests.

Frequently asked questions

1.Is JWT less secure than sessions?
Neither is inherently less secure. JWTs are harder to revoke and easier to leak in logs; sessions require server state. Pick based on architecture, not fashion.
2.Should I encrypt my JWTs (JWE)?
Only if the payload contains data the client should not read. Otherwise a signed JWS over HTTPS is enough.
3.How do I rotate JWT signing keys?
Publish both old and new keys in JWKS with distinct kid values, sign new tokens with the new key, retire old key after all old tokens expire.
4.Can I revoke a JWT?
Not the token itself. Either use short expiry + refresh flow, or maintain a denylist in Redis keyed by jti.