Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessObtain legitimate JWT assertion from shared-key service
-
DeliveryReplay assertion to target server token endpoint
-
ExploitDefault get_audiences() returns empty, aud only checked for presence
-
ExecutionServer issues cross-boundary access token
-
ImpactAccess protected resources of second service
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A07:2025 - Authentication Failures
ASVS 5.0
V6 - Authentication Authentication mechanism validation
MITRE ATT&CK
2 techniques across 2 tactics: Defense Evasion, Initial Access The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires three concrete conditions, all stated in the advisory: (1) the target authorization server uses Authlib's default authlib.oauth2.rfc7523.JWTBearerGrant and does NOT override get_audiences() with its own valid audience identifiers; (2) that server shares the same JWT signing key with another authorization server; and (3) the attacker already holds a legitimately issued JWT bearer assertion for some other audience (obtained as a low-privilege principal, hence PR:L). The limiting factors that reduce real-world risk: implementations that override get_audiences() to return the server's valid audience identifiers are explicitly NOT affected, and the two servers must share signing key material - without a shared key the forged/replayed assertion will not validate. This is NOT a default-everywhere remote-unauthenticated flaw; it is an authorization-boundary bypass specific to shared-key, default-grant deployments (notably microservice architectures sharing identity infrastructure). |
| Impact | This is a genuine authentication/authorization-boundary flaw (CWE-287/CWE-1188) but its real-world severity is gated by meaningful preconditions, which the CVSS 6.8 (medium) score reflects well. The vector CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N is internally consistent with the description: AV:N (the attack is delivered to a network token endpoint), AC:H (exploitation depends on conditions outside the attacker's direct control - two authorization servers must share the same JWT signing key and the target must run the default JWTBearerGrant without overriding get_audiences()), and PR:L (the attacker must already hold a legitimately issued JWT assertion, i.e. have authenticated somewhere as a low-privilege principal). A public, detailed PoC is published in the GHSA advisory and was independently reproduced and validated by its authors (a University of Sydney research team); it is not distributed as a packaged weaponized exploit, so treat it as a working reproducer rather than drop-in attack tooling. There is NO CISA KEV listing, so this is not confirmed actively exploited, and NO EPSS score was supplied in the input, so exploitation probability cannot be quantified from the data. The vuln.today decision label is 'this_month' (not act_now/emergency), consistent with a real-but-conditional authorization bypass rather than a widespread emergency. One signal worth flagging: the described impact crosses a trust boundary between two authorization servers, which could arguably justify a scope change (S:C) rather than the supplied S:U - defenders operating shared-key microservice fleets should weight this higher than the raw score suggests. |
| Exploit ScenarioDerived | In a microservice or federated environment where several authorization servers share the same JWT signing key, an attacker legitimately obtains a JWT bearer assertion from one low-privilege service (with aud set to that service, e.g. https://evil.test/token). They replay that assertion to a second server's token endpoint; because the second server uses the default JWTBearerGrant whose get_audiences() returns an empty list, verify_claims() only confirms an aud claim is present without matching it to the local endpoint, and the server issues an access token across the trust boundary. A full reproducer PoC is published in the GHSA advisory and was reproduced by the reporting researchers. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 22, 2026
Authlib's default RFC 7523 JWT bearer grant, in all releases prior to 1.9.0, fails to bind an incoming JWT assertion to the authorization server that receives it, because JWTBearerGrant.get_audiences() returns an empty list and verify_claims() therefore only checks that an aud claim is present rather than that it matches the server's token endpoint. An attacker who already holds a legitimately issued assertion for a different audience (obtained as a low-privilege principal) can replay it against a second authorization server that uses the default grant and shares the same JWT signing key, and receive an access token across that trust boundary. Exploitation requires all three conditions to hold - default grant without a get_audiences() override, shared signing key material, and a valid assertion for some other audience - so implementations that override get_audiences() with their own audience identifiers are explicitly not affected; the issue is not listed in CISA KEV and no in-the-wild exploitation is reported, although the vendor advisory includes a proof-of-concept script that demonstrates the bypass against Authlib's own Flask test fixtures.
RemediationAI
Vendor-released patch: 1.9.0 - upgrade the authlib pip package to 1.9.0 or later (release notes at https://github.com/authlib/authlib/releases/tag/v1.9.0, advisory at https://github.com/authlib/authlib/security/advisories/GHSA-fch4-3c6x-j4gc). After the upgrade, any JWTBearerGrant whose get_audiences() still returns an empty list will reject assertions outright with an invalid_grant error, so every deployment using the JWT bearer grant must implement get_audiences() to return the server's valid audience identifiers (typically its own token endpoint URL) before or alongside the upgrade, otherwise the grant stops functioning. For deployments that cannot upgrade immediately, the equivalent compensating control is to override get_audiences() on the grant subclass so it returns the concrete expected audience values; this is exactly the configuration the advisory states is not affected, and it closes the bypass because the aud claim is then matched against an explicit list instead of only being checked for presence. A second, independent control is to stop sharing JWT signing keys between authorization servers and give each server its own key material, so an assertion minted for one service will not validate at another; the trade-off is additional key management and rotation overhead per service. Restricting network reachability of the token endpoint does not address the issue, since the attacker is using a legitimate assertion against the same endpoint. Both the pull request (https://github.com/authlib/authlib/pull/945) and the commit (https://github.com/authlib/authlib/commit/e3bd41cb29dcfee434453b135ffb487884baeedf) are public and show the exact code change.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The flaw sits in Authlib's implementation of RFC 7523 (JWT bearer grant / JWT client authentication), specifically authlib.oauth2.rfc7523.JWTBearerGrant. In the affected versions the base class's get_audiences() returns an empty list, and the grant passes that list into the JOSE layer as an audience requirement; when the list is empty, no expected-value constraint is applied for the aud claim, so verification degrades to a presence check. The advisory also identifies authlib.jose.jwt.decode() used with claims_options for audience validation, and authlib.integrations.flask_oauth2.ResourceProtector.validate_request() with audience checking enabled, as entrypoints where the same weak default matters. The root cause class is CWE-287 (Improper Authentication), with the advisory additionally classifying it as CWE-1188 (Insecure Default Initialization of a Resource) because the unsafe behaviour is the framework's default rather than an opt-in. Context for the severity: JWT assertion replay across servers is only possible when both servers validate assertions with the same signing key, and the attacker must already possess a genuinely signed assertion for another audience - this is an authorization-boundary bypass in shared-key, multi-service identity deployments (notably microservice architectures), not a credential-less remote compromise. The 1.9.0 fix removes the permissive path: the grant now raises InvalidGrantError with 'No audience identifiers configured for this authorization server' when get_audiences() returns an empty list, the aud requirement is always marked essential with explicit allowed values, and the docstring is changed from SHOULD to MUST for implementing get_audiences(). Earlier releases had only emitted a deprecation warning that audience validation would become mandatory. The fixed release also bundles unrelated hardening in authlib/jose/rfc7518/oct_key.py, where the unsafe-key import check now scans for marker strings anywhere in the raw key rather than only at the start, plus scope-handling corrections in the OIDC hybrid/implicit grants.
Know when Authlib gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N
AV:N via token endpoint; AC:H because a shared signing key plus unoverridden default grant are required; PR:L because the attacker must hold a legitimate assertion; C/I:H from unauthorized cross-boundary token, A:N.
Primary rating from Vendor (GitHub_M).
CVSS VectorVendor: GitHub_M
Lifecycle Timeline
1DescriptionCVE.org
Authlib is a Python library which builds OAuth and OpenID Connect servers. Prior to 1.9.0, the default RFC 7523 JWTBearerGrant.get_audiences() returns an empty list, causing JWTBearerGrant.verify_claims() to require only that an aud claim exists without matching the current authorization server. An attacker holding a legitimate assertion for another service can present it to a server that shares the signing key and uses the default grant, obtaining an access token across a trust boundary. Implementations that override get_audiences() with the server's valid audience identifiers are not affected. This issue is fixed in version 1.9.0.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.
Authlib is a Python library which builds OAuth and OpenID Connect servers. [CVSS 5.7 MEDIUM]
Authentication bypass in Authlib (Python OAuth/OpenID Connect library) versions 1.6.5 through 1.6.6 allows remote attack
Authlib is a Python library which builds OAuth and OpenID Connect servers. Rated high severity (CVSS 7.5), this vulnerab
Authlib's JOSE/JWS verification path (through 1.6.4, with 1.6.5 as the fix) decodes attacker-supplied JWT/JWS header and
lepture Authlib before 1.3.1 has algorithm confusion with asymmetric public keys. Rated high severity (CVSS 7.5), this v
Unbounded DEFLATE decompression in Authlib's JWE zip=DEF handling (authlib/jose/rfc7518/jwe_zips.py) lets a small, valid
Signature verification bypass in Authlib 1.7.2 and earlier allows unauthenticated remote attackers to have crafted JWS J
Poisoned OAuth/OIDC discovery metadata in Authlib 1.7.2 and earlier allows an attacker who controls or intercepts the me
Authentication bypass in the joserfc Python library before 1.7.4 lets remote, unauthenticated attackers submit a JWS Gen
Token forgery in the Authlib Python library before 1.9.1 lets a remote, unauthenticated attacker mint HS256, HS384 or HS
Authentication bypass in Authlib's deprecated-but-still-shipped authlib.jose module (1.3.1 through 1.8.0, fixed in 1.9.0
Server-side request forgery in Authlib's RFC 9101 JWTAuthenticationRequest (JAR) extension lets unauthenticated remote a
EUVD-2026-108520
NVD
CVE.org
EPSS
GitHub
Exploit-DB