Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JWTPatterns

Adversarial JWT library test harness: 8 libraries, 4 ecosystems, RFC 7515 compliance.

Nine attack variants. 72 test results. Six of eight libraries ship parsers that silently accept tokens with unprocessed critical extensions — a MUST-level RFC 7515 requirement that has been in the spec since 2015.

The field report

The companion article, Six of Eight JWT Libraries Ship Non-Compliant Parsers, is the writeup. This repo is the artifact. Every claim in the article traces to a committed test file and a row in results/matrix.json.

What is in here

The corpus is static and committed: one JSON file per attack variant in fixtures/corpus/, built by fixtures/generate.js from the committed test-only keypairs in fixtures/keys/ (RSA-2048 and EC P-256). Every library sees the same tokens, so the comparison is clean.

Each harness is self-contained with its own dependency manifest. Harnesses run the corpus in default configuration — no extra options, no hardening, exactly what you get when you call the library's verify function with a key and a token.

The attack variants

# Variant What it tests
1 RS256 to HS256 algorithm confusion forged token signed with the server's RSA public key as an HMAC secret
2 alg:none unsigned token with no signature
3 alg case normalization NONE, nOnE, None, \nnone — does the parser normalize before checking?
4 jwk header injection embedded attacker-controlled public key
5 jku header injection URL pointing to an attacker-controlled JWK set
6 Empty signature valid header.payload with a trailing dot and no signature bytes
7 kid SQL injection kid set to ' OR '1'='1 — does it propagate to a key lookup?
8 crit unknown extension token declaring crit:["x-custom"] with an unrecognized extension
9 Clock skew defaults nbf in the future, exp in the past, with no tolerance configured

The libraries

Library Ecosystem Version
jsonwebtoken Node.js 9.0.3
jose Node.js 5.10.0
fast-jwt Node.js 5.0.6
PyJWT Python 2.13.0
python-jose Python 3.5.0
golang-jwt Go v5.2.2
lestrrat-go/jwx Go v2.1.4
Microsoft.IdentityModel .NET 8.18.0

Requirements

  • Node.js (fixtures and runner)
  • Python 3 + pip
  • Go
  • .NET SDK

Run the battery

From the repo root:

./runner/run-all.sh

This installs each harness's dependencies, runs every harness against the corpus, and writes result fragments to results/tmp/. It runs clean on macOS ARM64.

Read the results

runner/aggregate.js reads all fragments and writes results/matrix.json:

  • library_versions — versions captured at run time
  • results[variant][library] — one entry per library per variant, with three fields:
    • resultSAFE (rejected correctly) or VULNERABLE (accepted a token it should have rejected), or ERROR if the harness failed
    • note — the library's actual error message or observed behavior
    • reproducer — the harness test file that produced the entry
{
  "generated": "2026-05-31T13:27:12.308Z",
  "library_versions": {
    "jsonwebtoken": "9.0.3",
    "jose": "5.10.0"
  },
  "results": {
    "alg_confusion_rs256_hs256": {
      "jsonwebtoken": {
        "result": "SAFE",
        "note": "jsonwebtoken rejected algorithm confusion: invalid algorithm",
        "reproducer": "harnesses/node-jsonwebtoken/tests/01_alg_confusion.test.js"
      }
    }
  }
}

Re-aggregate without re-running the battery:

node runner/aggregate.js

Project structure

fixtures/     # corpus + keys (committed)
  corpus/     # one JSON file per attack variant
  keys/       # test-only RSA-2048 / EC P-256 keypairs
harnesses/    # one self-contained harness per library (Node, Python, Go, .NET)
runner/       # run-all.sh orchestration + aggregate.js
results/      # matrix.json (committed); tmp/ fragments (gitignored)
tests/        # root-level test area; each harness owns its own tests

License

MIT. See LICENSE.

About

Adversarial JWT library test harness: 8 libraries, 4 ecosystems, RFC 7515 compliance.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages