On this page (7 sections)

Authlib, a Python library for OAuth and JOSE (the authlib.jose module), has a critical flaw in how it verifies JSON Serialization JWS objects. According to the GitHub advisory, the JsonWebSignature.deserialize_json() method can return a payload as successfully verified without checking any signature and without needing a cryptographic key. It is tracked as CVE-2026-96760 and fixed in Authlib 1.9.0.

If your Python application uses Authlib to verify signed tokens or messages that arrive from outside, and it calls this method, an attacker may be able to forge identity or role claims. Teams running Python APIs, identity services and OAuth integrations should check their dependencies now.

What happened

The advisory was published to the Authlib repository on Oct 14, 2026 and reviewed in the GitHub Advisory Database on Oct 27, 2026. The CVE record lists the weakness classes as CWE-20, CWE-347, CWE-358 and CWE-670, which cover improper input validation, improper verification of a cryptographic signature and incorrectly implemented security checks.

So far the research shows one independent publisher covering the story, so most details below come from the maintainers' advisory and the CVE record rather than from separate confirmation.

The sources disagree on two points. The CVE record gives CVSS 9.8 while the GitHub advisory shows 9.1. The CVE description says v1.7.2 and below, while the package data and advisory say <= 1.8.0. Treat 1.8.0 and earlier as affected, which is the safer reading, and rely on 1.9.0 as the fixed version.

How the flaw works

A JWS in JSON Serialization can carry several signatures in a signatures array. A verifier should confirm that at least one valid signature exists. Per the advisory, Authlib's code starts with a flag set to true, and only sets it to false from inside a loop over the signatures. If the array is empty, the loop never runs, the flag stays true and the payload is returned as verified.

This is a classic fail-open pattern: the safe outcome (reject) requires work to happen, while the unsafe outcome (accept) is the default. No key is consulted because no signature is examined.

The advisory's own tests make the scope clear:

  • A genuine object with valid signatures is accepted, so a vulnerable deployment looks healthy in normal use.
  • An object with a corrupted signature is rejected, so ordinary tampering is still caught.
  • An object with the signatures member removed entirely is rejected with a decode error, so the problem is specific to an empty array.
  • An empty array is accepted both with no key and with the real key, so holding the correct key does not protect the caller.

The advisory also notes that joserfc 1.7.5, the library Authlib's deprecation warning points users to, rejects the same object. We are not reproducing the test input here; the fix and detection steps below are what matter for defenders.

Who is affected

You are exposed if all of these are true:

  • Your project depends on the authlib package from PyPI at version 1.8.0 or earlier.
  • Your code calls JsonWebSignature.deserialize_json() (the authlib.jose JWS module).
  • The input comes from a party you do not control, such as a request body, header or message from a client or partner.

The advisory states that where the accepted payload carries identity or authorisation claims, the result is a complete authentication bypass by an unauthenticated remote caller with no key material. If you only verify compact-serialization tokens through other code paths, the advisory does not say those are affected, so confirm by reading your own code rather than assuming.

How to check your exposure

First, find which Authlib version each environment actually has. This read-only command prints the installed version and metadata; run it inside each virtualenv or container. A version of 1.8.0 or lower is affected.

Show the installed Authlib version (run inside each Python environment)Shell
pip show authlib

Next, look for the vulnerable call in your own source. This read-only search lists every line that calls the method; run it from the project root. Any hit that handles external input deserves review.

Find calls to the affected method in your code (run from the project root)Shell
grep -rn "deserialize_json" --include="*.py" .

Also check lock files such as requirements.txt, poetry.lock or Pipfile.lock, and any container images built earlier, since an old image may still ship a vulnerable version even after you update the repository.

What to do now

The fix is to upgrade to Authlib 1.9.0. Test before deploying, because the upgrade changes a dependency in your authentication path.

Caution. Upgrading a library used for authentication can change behavior and requires a redeploy or service restart. Run your test suite and any login or token flows in staging first.

This command upgrades Authlib to the fixed release; run it inside the target Python environment, then confirm with pip show authlib that the version is 1.9.0 or higher.

Upgrade Authlib to the fixed release (run inside the target Python environment)Shell
pip install --upgrade "authlib>=1.9.0"

Then restart the application so the new code is loaded.

Tip. As defense in depth, never treat a successful signature parse as authorization on its own. Check the issuer, audience, expiry and the specific claims your application needs after verification.

Detection and monitoring

No exploitation has been reported in the research, but the bypass needs only a crafted request, so look back through your logs. Useful signals include requests whose body contains a JSON JWS with an empty signatures list, sudden privilege changes, and accounts acting with roles they were never granted.

Add a regression test to your own suite that feeds an empty signatures array to your verification path and expects a rejection. Track the dependency going forward with an automated dependency audit so the next advisory reaches you quickly; the plugin vulnerability guide explains the same habit of checking components against known issues for WordPress.

If the affected app is a public website or API, an outside-in check will not see library versions, but you can still review the exposed surface. Webforta Scan runs read-only security scans of sites you verify, and the security headers checker is a free way to review your response headers while you are in there.

Timeline

Key dates from the advisory and CVE record
DateEvent
Sep 28, 2026Publication date listed in the CVE record
Oct 14, 2026Advisory published to the authlib/authlib repository
Oct 27, 2026Advisory reviewed and last updated in the GitHub Advisory Database
The CVE record lists a published date of 2026-09-28, earlier than the GitHub advisory dates. The research does not explain the difference, so treat the exact disclosure sequence as unclear.

Sources

This article is based on the public sources below. Details can change as vendors and researchers publish more; check the original advisories before acting on version numbers.

  1. CVE-2026-96760 - GitHub Advisory Databasegithub.com
  • Authlib
  • Python
  • JWS
  • authentication bypass
  • CVE-2026-96760