Skip to content
← Blog · · df00tech

Authlib < 1.9.0: Empty-Signature JWS Bypass Lets Attackers Forge Verified Payloads

breaking ghsa pip CVE-2026-96760 #checker-reject

What happened

A GitHub Security Advisory (GHSA-6v38-4h7w-rj9h, tracked as CVE-2026-96760) reports that authlib versions prior to 1.9.0 contain a signature verification bypass in JsonWebSignature.deserialize_json(). According to the advisory, the JWS JSON Serialization deserializer in authlib/jose/rfc7515/jws.py initializes a validity flag to True before any signatures are checked, and only flips it to False inside a loop over the object's signatures array. If an attacker submits a JWS JSON object with an empty signatures array, the loop body never executes, the flag stays True, and the payload is returned as "verified" — without a signature ever being examined and without any key material being consulted.

The advisory includes a reproduction showing this behavior on authlib 1.8.0: a forged payload with signatures: [] is accepted whether or not a real key is supplied, while the same library correctly rejects tampered signatures or a missing signatures member entirely — indicating the bug is specific to the empty-array case. The advisory also notes that joserfc, the library authlib's own deprecation warning points users toward, does not exhibit this behavior on the equivalent input.

Why it matters for defenders

Per the advisory, any relying party that calls JsonWebSignature.deserialize_json() on attacker-influenced input is affected. The CVSS score given is 9.1, and exploit status is listed as proof-of-concept public, meaning working exploitation code is already available. Where the deserialized payload carries identity or authorization claims (session tokens, SSO assertions, federation messages), this is described as a complete authentication bypass achievable by an unauthenticated remote caller with no key material — a deployment can appear fully functional (genuine signed objects still validate correctly) while forged, signature-less objects are silently accepted alongside them.

Who's affected

  • Python services using authlib (pip package) prior to 1.9.0
  • Specifically, any code path that calls JsonWebSignature.deserialize_json() on JWS JSON Serialization input from an untrusted or external source

What defenders should do now

  • Inventory services for authlib usage and check the installed version; upgrade to 1.9.0 or later where deserialize_json() is used, per the advisory.
  • Identify and audit any code paths that pass externally-supplied JWS JSON Serialization objects into deserialize_json(), particularly where the result feeds authentication or authorization decisions.
  • As a hunting angle, review application or API logs for incoming JWS JSON objects with an empty or missing signatures array, which is anomalous for legitimately issued tokens.
  • As a stopgap where upgrading isn't immediately possible, consider validating that signatures is non-empty before passing objects to the deserializer, or evaluate migrating to joserfc, which the advisory states handles this case correctly.
  • Treat this as a supply-chain-style exposure: the vulnerable code path can be several layers removed from application code, so dependency scanning alone may not surface affected call sites — trace actual usage of the deserialization method.

Developing intel

This is based on a same-day GitHub Security Advisory; details may be refined as the project and downstream consumers respond. For the full technical writeup, reproduction steps, and the proposed fix (PR #938 referenced in the advisory), see the original GHSA-6v38-4h7w-rj9h advisory.

Get new detections in your inbox

New ATT&CK coverage plus CISA KEV / CVE detection rules, roughly weekly. No spam, unsubscribe anytime.