Sign inCreate account

← all recent vulnerabilities

criticalPublished September 11, 2026

PyJWT: attackers can forge login tokens when a public key is also accepted as a password

Identifiers: CVE-2026-102268 · GHSA-ffc3-869f-jxw9 · CVSS 3.1 9.1 (scored by GitHub)

What it is

PyJWT is meant to refuse a public key used as an HMAC secret. That check is skipped when the PEM key has unusual whitespace or line endings, so an attacker who knows your public key (it is public) can sign their own HS256 token and your server accepts it: they log in as anyone. It only happens when jwt.decode allows both an HMAC and an asymmetric algorithm, such as ['RS256', 'HS256'], with the key passed as raw PEM.

Who is affected

Versions inside these ranges are affected. The fixed versions are the ones to move to.

RegistryPackageAffectedMove to
PyPIpyjwt
<= 2.13.0
2.14.0

How to check

Run one of these in your project's folder; the first two download the CLI and check its SHA-256 first:

Linux (x86_64 or arm64), WSL and CI runners
d="$(mktemp -d)" && a="xsec-$(uname -m | sed s/arm64/aarch64/)-unknown-linux-musl.tar.gz" && curl -fsSL -o "$d/$a" "https://github.com/xtruct-col/xsec-action/releases/latest/download/$a" && curl -fsSL -o "$d/checksums.txt" "https://github.com/xtruct-col/xsec-action/releases/latest/download/checksums.txt" && (cd "$d" && grep " $a$" checksums.txt | sha256sum -c -) && tar -xzf "$d/$a" -C "$d" xsec && "$d/xsec" deps
macOS or Windows, with Docker
docker run --rm -v "$PWD:/src" -w /src alpine:3.20 sh -c 'apk add -q curl && d="$(mktemp -d)" && a="xsec-$(uname -m | sed s/arm64/aarch64/)-unknown-linux-musl.tar.gz" && curl -fsSL -o "$d/$a" "https://github.com/xtruct-col/xsec-action/releases/latest/download/$a" && curl -fsSL -o "$d/checksums.txt" "https://github.com/xtruct-col/xsec-action/releases/latest/download/checksums.txt" && (cd "$d" && grep " $a$" checksums.txt | sha256sum -c -) && tar -xzf "$d/$a" -C "$d" xsec && "$d/xsec" deps'
Already have the CLI?
xsec deps

Or look up pyjwt in your lockfile and compare the version with the ranges above.

How to fix it

Upgrade PyJWT to 2.14.0 or later. Until then, allow one algorithm per jwt.decode call (for example algorithms=['RS256']) or load keys through PyJWK.

Sources

This list is curated by hand and kept short on purpose: it is not every known vulnerability, and a clean xsec deps does not mean no dependency has a flaw. Use your package manager's audit (npm audit, pip-audit, bundle audit) or Dependabot for the rest.