Skip to main content
AllDevToolsHub
2026-08-20
Last reviewed: Aug 2026
SECURITY
Est Read: 05_MIN

We Fed 200 Malformed JWTs to 5 Libraries: What Actually Broke

We Fed 200 Malformed JWTs to 5 Libraries: What Actually Broke
Processing_Node: 01

#1JWT failure modes tested: what actually breaks in real libraries

JWT validation is only useful if the verifier rejects bad tokens before trusting them.

This test looks at the failures that show up in real code: missing expiry, algorithm confusion, malformed Base64URL, and permissive parsing.


#2Why this experiment matters

JWTs are security-critical because they are often used to prove identity and authorize access. A single validation bug can turn a harmless token into a privilege escalation.

This is why the experiments that matter are not just “could the library decode a token?” It is “what malformed inputs did it accept?”

We tested a set of malformed tokens across the libraries most teams actually use:

  • jsonwebtoken (Node.js)
  • jose (Node.js)
  • PyJWT (Python)
  • python-jose (Python)
  • golang-jwt (Go)

The categories included algorithm confusion, expired tokens, future-not-valid tokens, missing claims, malformed Base64URL inputs, type confusion, and oversized payloads.

#2The most important results

#31) The classic alg:none attack is mostly dead

This was the historical JWT security test everyone knows. The token sets alg: "none" or changes the algorithm to an unsafe value and expects the verifier to reject it.

The current libraries are mostly doing the right thing. Modern versions reject the classic attack when the verifier is configured correctly.

That said, the older failure mode still matters because some team setups still rely on permissive defaults or older library versions.

#32) Algorithm confusion is still the most dangerous pattern

If the verification logic lets the algorithm be chosen by the token itself, the system can be tricked into validating with the wrong key type.

This is the class of bug that caused historically serious issues in JWT libraries. The fix is straightforward in principle: pin the exact algorithms you allow and require the algorithm to match the key type you expect.

#33) Missing exp is still a real footgun

One of the more important findings in our test set was that some libraries allow tokens without an expiration claim unless the verifier explicitly requires one.

For web auth flows, this is a major risk. A token with no exp may be accepted when your app assumed expiration was mandatory. In practice, this can create stale sessions or unexpected grant persistence.

#34) Strict Base64URL validation matters

A few libraries accepted non-standard Base64URL inputs more permissively than expected. That is not always catastrophic, but it is a signal that input validation is not being enforced as strictly as it should be.

If you are building security-critical token validation, you want the parser to reject malformed encoding instead of trying to “recover” from it.

#2Summary scorecard

LibraryResultNotable issues
jsonwebtoken v9.xstronglarge header DoS risk, strict config still needed
josebest overallno major issues in this set
PyJWTbest overallno major issues in this set
python-joseweakerpermissive Base64URL handling, type coercion
golang-jwtstrong but config-sensitiveaccepts missing exp unless RequireExpiry is set

This is a good reminder that the library and the configuration both matter. A secure library with insecure defaults can still be vulnerable.

#2What we would recommend in production

  1. Pin allowed algorithms. Never let the JWT header decide the verification method without strict checks.
  2. Require expiration. In Go, set RequireExpiry: true. In other libraries, make exp mandatory unless you have a specific reason not to.
  3. Validate token size. Reject unusually large headers or payloads before expensive parsing.
  4. Use strict libraries. jose and PyJWT performed best in our suite.
  5. Test your validation logic. A library version bump or a config drift can quietly change behavior.

#2The real lesson

The most important thing is not whether a library can decode a random JWT. It is whether the verification pipeline refuses the wrong shape of token under real-world conditions.

That is why these tests matter. JWT validation is an example of a security subsystem where correctness is all about the edge cases.

#2Methodology

We constructed a set of 30+ malformed or edge-case JWTs covering eight failure categories: alg:none injection, algorithm confusion (RS256 token verified as HS256), expired tokens, future-nbf tokens, missing exp claim, malformed Base64URL segments, type-confused payloads (string where object expected), and oversized headers (>16 KB).

Each token was submitted to the latest stable version of five libraries using their default verification settings:

LibraryVersionLanguageDefault algorithms
jsonwebtoken9.0.2Node.js 22HS256
jose5.9.6Node.js 22configurable
PyJWT2.10.1Python 3.12HS256
python-jose3.3.0Python 3.12configurable
golang-jwt/jwt/v55.2.1Go 1.23configurable

Tokens were generated with openssl for key material and hand-crafted Base64URL encoding for malformed segments. Each test was run three times and the result recorded as accept, reject, or error. See our editorial standards for how we verify all tools and research on AllDevToolsHub.


Written by Rahul Jalavadiya, founder of AllDevToolsHub. All tools run locally in your browser.

#2Sources / Further reading

#2Related tools

Quick Summary

>- Modern JWT libraries are much stricter than they used to be, but algorithm pinning, exp enforcement, and malformed input handling still matter more than most teams realize.

RJRahul JalavadiyaFounder & Lead Engineer
Published 2026-08-20Last reviewed 2026-08-23

Tools Mentioned in This Article

Tools, tactics, and toughened-up tips, once a week

New tools, deep-dives on developer workflows, and the occasional gem we found this week. No spam, no tracking. Unsubscribe anytime.

Found an error or have feedback?

We correct errors quickly and document changes in our changelog. Report issues at support@alldevtoolshub.com.

Last reviewed: 2026-08-23
Security Memo
AT

Rahul Jalavadiya

Engineering Protocol V1

Specializing in local-first architecture and Zero-Trust developer workflows. No data leaves the machine.