Still present in 42% of npm dependency trees we crawl. Stop shipping it.
Legacy versions accept untrusted secret-key inputs that collide trivially with attacker-chosen algorithms. A one-line upgrade fixes it. Your excuse runs out here.
§1 · Context
CVE-2022-23529 hit jsonwebtoken versions prior to 9.0.0. The fix
shipped the next month. And yet, crawling the public npm dependency
graph in April 2026, we still find version ranges below 9.0.1 in 42% of
trees — often pinned by a transitive dependency that never updated its
manifest.
§2 · The bug, briefly
The verify() function accepts a secretOrPublicKey parameter that was
historically typed loosely. A call pattern common in example code allows
a caller to pass an object where the library expects a string; the
attacker-controlled alg field of the JWT then negotiates a matching
key shape, producing a "valid" signature the library cheerfully accepts.
The fix is a handful of runtime type checks. There is no performance
excuse.
§3 · Why it persists
Most of the 42% are packages that use jsonwebtoken transitively,
through an unmaintained auth middleware layer from 2019. The root cause
is not the library. The root cause is a culture that reads ^8.0.0 as
"pinned enough."
§4 · What to do today
Run npm audit with --production --audit-level=high. If you see this
CVE, you have ten minutes of work to do: add a resolutions or
overrides block pinning the transitive dep to >=9.0.1, redeploy,
verify.