Authlib through 1.8.0 accepts a JWS JSON object with no signatures as verified (CVE-2026-96760, 9.1); fixed 1.9.0
TL;DR
Authlib's JsonWebSignature.deserialize_json() returned the payload of a JWS JSON Serialization object as verified when its signatures array was empty, so a relying party that fed it untrusted tokens accepted attacker-written claims with no key involved (CVE-2026-96760; CISA-ADP 9.8, GitHub 9.1). The CERT/CC record from 2026-09-28 says "1.7.2 and below", but 1.8.0 (PyPI 2026-08-30) was also vulnerable; the fix is PR #938 in 1.9.0 (PyPI 2026-10-14), whose release notes carry no security wording. Upgrade to 1.9.0 or later and check whether any token your service accepts is parsed through the JSON-serialization path.
What happened
- 2026-08-21. CERT/CC notified the vendor (VU#762428, "Vendor Notified" field). The note says no statement was received and the vendor could not be reached to coordinate.
- 2026-08-30. Authlib 1.8.0 reached PyPI, still carrying the bug.
- 2026-09-28. CERT/CC published VU#762428 and CVE-2026-96760 as the CNA:
JsonWebSignature.deserialize_json()accepts a JWS object whosesignatureslist is empty and "returns the payload as successfully verified without checking for a signature and without requiring a cryptographic key"; thedeserialize()wrapper reaches the same code. Affected "up to and including 1.7.2"; fixed version "None". CISA's ADP added CVSS 3.1 9.8. The GitHub Advisory Database mirrored it the same day as GHSA-6m87-8wg6-hh8w with< 1.9.0and no patched version. - 2026-10-05. Per the advisory now on the vendor repository, the only fix at that date was the unmerged pull request #938, and the GitHub record had no machine-readable range, so OSV-based scanners reported 1.8.0 as clean.
- 2026-10-14. GHSA-6v38-4h7w-rj9h was published on
authlib/authlib(Critical, CVSS 3.1 9.1,AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N, CWE-347) under the title "Signature verification bypass (CVE-2026-96760) is live in the current release 1.8.0, which every published record excludes". Its text: "This is already public. What is new is the version range." Root cause as stated there: the validity flag starts true and is only set false inside the loop oversignatures, so an empty array never fails. Credits: zer0d4y5, uziii2208, nguyenminhtuan28. The same day Authlib 1.9.0 and 1.9.1 reached PyPI; the 1.9.0 release notes list "Fix empty signatures validation in JWS JSON deserialization" (PR #938) beside four OAuth validation fixes, with no CVE and no security label. - 2026-10-27. The database reviewed GHSA-6v38-4h7w-rj9h (affected
<= 1.8.0, patched 1.9.0) and withdrew GHSA-6m87-8wg6-hh8w as a duplicate. The row appeared on the reviewed-critical pip listing that morning.
Three affected ranges exist, and only one is right for an installed app. The CNA says 1.7.2 and below; the withdrawn mirror said below 1.9.0; the live vendor-repository advisory says 1.8.0 and below with 1.9.0 patched. The registry settles it: 1.8.0 was published nine days after vendor notification and before the fix, so a scanner keyed to the CNA range misses it. Treat anything below 1.9.0 as affected.
What a reader is exposed to. The compact serialization (a.b.c tokens, the common OAuth and OIDC path) is not the path the records describe; the bypass is in the JSON Serialization (RFC 7515 section 7.2) parser. A service that accepts JSON-form JWS from clients, partners or a microservice peer, or that passes untrusted input into deserialize() without knowing which form arrives, can be handed a payload with forged sub, roles or scopes. CERT/CC lists authentication bypass, forged inter-service messages and forged permissions as the consequences.
Am I affected?
pip show authlib 2>/dev/null | grep -i ^version # below 1.9.0 is affected
grep -rn "deserialize_json\|JsonWebSignature\|\.deserialize(" --include=*.py . | grep -v site-packages
- A version at or below 1.8.0 is affected. The CNA's "1.7.2 and below" undercounts by one release.
- The grep tells you whether the JSON-serialization parser is reachable from input you do not control. If every token you verify is compact-form and comes from
jwt.decode()with a key, the records describe a path you may not be using; upgrade anyway, because the 1.9.0 notes also tighten OAuth key, scope, audience, nonce and JAR validation.
If you are affected
- Upgrade to
authlib>=1.9.0and redeploy; the fix is in the parser, not in configuration. - If untrusted JSON-form JWS reached a vulnerable version, audit the identities those tokens asserted against your own records for the window since the service first accepted them. Auditing a vibe-coded repo and if your webapp was compromised.
Prevention
- Pin and audit auth libraries separately from the rest of the tree, because a fix release here carried no security wording and an aggregator range excluded a vulnerable version for six weeks. Package vetting checklist.
- Verify tokens with an explicit key and algorithm allowlist and reject any JWS whose signature list is empty before handing it to a library.
Sources
- CERT/CC VU#762428 — Authlib library contains a signature-verification bypass vulnerability — fetched 2026-10-27: published 2026-09-28, vendor notified 2026-08-21, affected "up to and including 1.7.2", fixed version "None", vendor status unknown, the impact list, acknowledgements.
- CVE Services — CVE-2026-96760 — queried 2026-10-27: CNA certcc, published 2026-09-28, affected 1.7.2, CISA-ADP CVSS 3.1 9.8, references to the repository and the VU note.
- authlib/authlib — GHSA-6v38-4h7w-rj9h — fetched 2026-10-27: published 2026-10-14 by azmeuk, Critical 9.1, the vector,
<= 1.8.0affected, 1.9.0 patched, the "already public, new is the version range" text, the flag-in-loop root cause, PR #938, credits. - GitHub Advisory Database — GHSA-6v38-4h7w-rj9h — fetched 2026-10-27: reviewed 2026-10-27, affected
<= 1.8.0, patched 1.9.0, references to PR #938, commit 6c11a02 and the v1.9.0 release. - GitHub Advisory Database — GHSA-6m87-8wg6-hh8w — fetched 2026-10-27: published 2026-09-28, withdrawn 2026-10-27 as a duplicate,
< 1.9.0, no patched version, CVSS 9.8. - authlib/authlib — release v1.9.0 — fetched 2026-10-27: dated 14 Oct, "Fix empty signatures validation in JWS JSON deserialization" (PR #938) and the four OAuth validation fixes; no CVE, no "security".
- PyPI
authlibrelease metadata, queried 2026-10-27: 1.7.2 on 2026-05-06, 1.8.0 on 2026-08-30, 1.9.0 and 1.9.1 on 2026-10-14; latest 1.9.1.