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.
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.
pip show authlibNext, 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.
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.
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.
pip install --upgrade "authlib>=1.9.0"Then restart the application so the new code is loaded.
0 of 8 done
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
| Date | Event |
|---|---|
| Sep 28, 2026 | Publication date listed in the CVE record |
| Oct 14, 2026 | Advisory published to the authlib/authlib repository |
| Oct 27, 2026 | Advisory reviewed and last updated in the GitHub Advisory Database |
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.
