CVE-2026-27962: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-27962 is a JWS JWK Header Injection vulnerability in the Python Authlib library (versions ≤ 1.6.8) that allows unauthenticated attackers to forge arbitrary JWT tokens and bypass signature verification entirely. The flaw was published on March 15, 2026, by the Authlib maintainer and assigned a CVSS v3.1 base score of 9.1 (Critical) (Github Advisory). It affects all Authlib releases prior to 1.6.9, as well as downstream IBM products including IBM Observability with Instana (OnPrem), IBM watsonx Code Assistant On Prem, and IBM watsonx Orchestrate with watsonx Assistant Cartridge (IBM Advisory). The vulnerability was credited to researchers Jaynornj and Pr00fOf3xpl0it (Github Advisory).

Technical details

The root cause is classified as CWE-347 (Improper Verification of Cryptographic Signature). The vulnerable code resides in authlib/jose/rfc7515/jws.py within the JsonWebSignature._prepare_algorithm_key() method (lines 272–273), where a fallback branch reads key = header["jwk"] when key=None and a jwk field is present in the JWT header — meaning the library uses an attacker-controlled key for signature verification (Github Advisory). The most common real-world trigger is a JWKS key resolver callable that legitimately returns None for an unknown or rotated kid value; the library then silently falls through to the attacker-embedded public key, making the substitution invisible to the application (Github Advisory). This behavior directly violates RFC 7515 §4.1.3 (which marks the jwk header parameter as "NOT RECOMMENDED" as a trust anchor) and §5.2 (which requires the verification key to come from application context, not the token itself). The same fallback pattern also existed in authlib/jose/rfc7516/jwe.py and was removed in the same patch commit (Patch Commit).

Impact

Successful exploitation allows an unauthenticated remote attacker to forge JWT tokens with arbitrary claims — including elevated roles such as admin, arbitrary scopes, or any user identity — without possessing any legitimate credentials or the server's signing keys (Github Advisory). The forged token is indistinguishable from a legitimate one because no exception is raised during verification, meaning application-level audit logs may not flag the intrusion. The confidentiality and integrity impacts are both rated High, as an attacker can access protected resources and perform unauthorized actions across any privilege level encoded in JWT claims; availability is not directly impacted (Github Advisory).

Exploitability

A proof-of-concept exploit script was published as part of the GitHub Security Advisory, demonstrating the attack in Python using authlib and cryptography libraries; however, the PoC operates entirely in-process and does not target a live server, so it is classified as a demonstration rather than a weaponized exploit (Github Advisory). There is no confirmed evidence of in-the-wild exploitation or threat actor attribution at this time (Feedly). The EPSS score is approximately 0.039% (low probability of exploitation within 30 days), and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities catalog. Detection plugins are available from Qualys (IDs 5009227, 761751) and Nessus (IDs 303588, 314275).

Exploitation steps

  1. Identify a vulnerable target: Locate an application that uses Authlib ≤ 1.6.8 for JWT/JWS validation, particularly one that uses a JWKS-based key resolver callable (e.g., looking up keys by kid from a cache or remote JWKS endpoint).
  2. Generate an attacker-controlled RSA or EC keypair: Use any standard cryptographic library (e.g., Python cryptography) to generate a 2048-bit RSA keypair or EC keypair.
  3. Craft a forged JWT payload: Construct a JSON payload with desired elevated claims, for example {"sub": "attacker", "role": "admin"}, encoded as bytes.
  4. Embed the attacker's public key in the JWT header: Build the JWT header as {"alg": "RS256", "jwk": <attacker_public_jwk>, "kid": "<unknown-or-rotated-kid>"}, where the kid value is one not present in the server's JWKS cache, causing the key resolver to return None.
  5. Sign the token with the attacker's private key: Use jws.serialize_compact(header, forged_payload, attacker_private) to produce a compact JWS token signed with the attacker's own private key.
  6. Submit the forged token to the target application: Send the crafted token in an HTTP Authorization: Bearer <token> header to any protected endpoint.
  7. Bypass verification: The server's key resolver returns None for the unknown kid; Authlib's fallback logic extracts the attacker's public key from the jwk header field and uses it to verify the signature — which passes. The forged claims are returned as authentic with no exception raised (Github Advisory).

Indicators of compromise

  • Network: Inbound HTTP requests carrying Authorization: Bearer tokens with unusually large or structured headers (base64-decoded JWT headers containing a jwk field with an embedded RSA/EC public key object); requests using kid values not present in the application's configured JWKS.
  • Logs: Application access logs showing successful authentication events for user identities or roles that do not correspond to any registered account; JWT validation logs (if instrumented) showing kid values that do not match any cached or configured key.
  • File System / Application State: No direct file system artifacts are expected, as the attack is entirely in-memory and network-based.
  • Process / Runtime: Unexpected privilege escalation events in application audit trails (e.g., admin-level actions performed by accounts with no prior admin history); absence of any authentication failure logs despite use of unknown kid values, which would normally indicate a key lookup miss (Github Advisory).

Mitigation and workarounds

Upgrade Authlib to version 1.6.9 or later, which removes the vulnerable fallback branch from both authlib/jose/rfc7515/jws.py and authlib/jose/rfc7516/jwe.py (Patch Commit, Release Notes). As an interim workaround, ensure that all key resolver callables explicitly raise an exception (e.g., MissingKeyError) rather than returning None when a key cannot be resolved for a given kid. Additionally, audit all application code that calls jws.deserialize_compact(), jws.deserialize_json(), or jws.deserialize() to confirm that key=None is never passed directly. IBM has released patches for affected products including IBM Observability with Instana (OnPrem), IBM watsonx Code Assistant On Prem, and IBM watsonx Orchestrate with watsonx Assistant Cartridge (IBM Advisory).

Community reactions

The vulnerability received coverage from security news outlets including The Hacker Wire, which published an article titled "Authlib Critical JWT Forgery CVE-2026-27962" shortly after disclosure (The Hacker Wire). Security Online Info also covered the issue in a broader piece on broken cryptographic key handling in Authlib (Security Online). Red Hat tracked the issue via Bugzilla with a high severity rating and a CC list of 37 users, indicating significant internal triage activity (Red Hat Bugzilla). OpenSUSE and Debian also issued security announcements for their packaged versions of python-authlib.

Additional resources

Linux Distribution fix status

Fix availability across major Linux distributions and their releases.

Debian

Fixed

bookworm

python-authlib: 1.2.0-1+deb12u2

Fixed

sid

python-authlib: 1.6.9-1

Fixed

trixie

python-authlib

Affected

Ubuntu

Fixed

devel

python-authlib

Unknown

jammy

python-authlib

Affected

jammy (esm-apps)

python-authlib: 0.15.5-1ubuntu0.1~esm2

Fixed

noble

python-authlib

Affected

noble (esm-apps)

python-authlib: 1.3.0-1ubuntu0.1~esm2

Fixed

resolute

python-authlib

Affected

resolute (esm-apps)

python-authlib: 1.6.7-1ubuntu0.1~esm1

Fixed

RHEL / CentOS

Unknown

Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-v2f8-6655-7grjCRITICAL10
  • Python logoPython
  • vibe-trading-ai
NoYesOct 02, 2026
CVE-2026-105782HIGH7.5
  • Python logoPython
  • scrapy
NoYesOct 06, 2026
GHSA-v853-p72q-4cfwHIGH7.5
  • Python logoPython
  • quart
NoYesOct 05, 2026
CVE-2026-105751MEDIUM6.9
  • Python logoPython
  • docling
NoYesOct 05, 2026
CVE-2026-105750MEDIUM5.9
  • Python logoPython
  • docling
NoYesOct 05, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management