Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.
Open advisories
21 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.
Summary RFC 7592 (OAuth 2.0 Dynamic Client Registration Management Protocol) lets a previously registered client read, update, or delete its own registration, authenticated by a `registration_access_token` issued specifically to that client at registration time. The entire security model of this protocol depends on the server verifying that the token presented in the request actually belongs to the client identified in the request, not merely that the token is valid for some client. Authlib's `ClientConfigurationEndpoint` implements the control flow correctly in structure, calling `authenticate_token`, then `authenticate_client`, then `check_permission`, and treats all three as abstract methods that "Developers MUST implement in subclass." The problem is that the documented example implementations for these methods, taken together exactly as written, never perform the one check that matters: binding the authenticated token to the specific client being accessed. A…
Recommended action: Upgrade to 1.9.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Reporter: Cavan Loughran, Celvex Group Inc. Summary Authlib's symmetric (oct) key handling accepts an empty key (empty bytes b'' / empty string '') as a valid HMAC signing and verification key. An empty HMAC key produces a deterministic digest that any party can reproduce, so an attacker who knows (or can cause) the application to verify a token with an empty key can forge arbitrary tokens that pass HS256/HS384/HS512 signature verification. This is the Authlib member of the cross-language empty-HMAC-key family already assigned CVE-2026-44351 (fast-jwt, npm) and CVE-2026-45363 (ruby-jwt, RubyGems). This is DISTINCT from Authlib's existing recent JWT-verification advisories. It is not closed by CVE-2026-27962 / GHSA-wvwj-cvrp-7pv5 (JWS JWK header injection, the key=None case), nor by CVE-2026-28802 / GHSA-7wc2-qxgw-g8gg (alg:none blank-signature bypass), nor by GHSA-5357-c2jx-v7qh (algorithm confusion with asymmetric public keys). Those address header-driven key injection, the none…
Recommended action: Upgrade to 1.9.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Authlib's RFC 9101 (JAR) extension passes the attacker-controlled `request_uri` authorization parameter straight to the `get_request_object()` fetch hook with no validation, at a pre-authentication endpoint. Authlib already defines the pre-registration allowlist for this (`request_uris` client metadata and `require_request_uri_registration` server metadata) but the extension never consults it, and both docstrings instruct integrators to implement the hook as an unrestricted `requests.get(request_uri)`. Deployments following the documented pattern get an unauthenticated SSRF primitive. Details Verified against authlib 1.7.2 and current `main`. All line numbers below are from `authlib/oauth2/rfc9101/authorization_server.py`. The extension registers itself on the `before_get_authorization_grant` hook (lines 62-65), so it runs on every authorization request before any user or client authentication. `support_request_uri` defaults to `True` (line 58). The only gate before…
Recommended action: Upgrade to 1.9.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
`OpenIDMixin.parse_id_token()` reads the `nonce_supported` claim from the ID token it is validating. When that claim is boolean `false`, the expected nonce is set to `None` and nonce validation is skipped for that token. An ID token that carries this claim is therefore accepted in a session whose nonce does not match. A captured, validly signed ID token belonging to a victim can be replayed into an attacker-controlled session, authenticating the attacker as the victim at the relying party. The code is identical in `authlib/integrations/base_client/sync_openid.py:82-83` and `authlib/integrations/base_client/async_openid.py:84-85`, so all framework integrations are affected. Fixed versions: none; reproduced on 1.8.0 (commit c529a61a). Preconditions: the ID token must carry a valid signature and pass `iss` and `aud` validation, and the attacker must be able to supply it to `parse_id_token()`. Authorization code flow is not affected. Implicit and hybrid relying parties, and…
Recommended action: Upgrade to 1.9.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Summary Authlib's default RFC 7523 JWT bearer grant leaves `get_audiences()` empty, so `verify_claims()` only checks that an `aud` claim *exists* instead of requiring it to match the current authorization server's token endpoint. An attacker holding a legitimately issued JWT assertion for *any* audience can present it to a different authorization server sharing the same signing key and obtain an access token. To be completely transparent, AI tools helped surface it. However, we have independently reproduced and carefully validated the issue. We follow responsible disclosure practices and are sharing this privately. Affected Entrypoints - `authlib.oauth2.rfc7523.JWTBearerGrant` — default `get_audiences()` returns empty list - `authlib.jose.jwt.decode()` with `claims_options` for audience validation - `authlib.integrations.flask_oauth2.ResourceProtector.validate_request()` when audience checking is enabled Exploit Path ``` 1. Attacker authenticates to Service…
Recommended action: Upgrade to 1.9.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Report metadata | Field | Value | | --- | --- | | Package | `authlib` (PyPI, `pkg:pypi/authlib`) | | Repository | https://github.com/authlib/authlib | | Component | `authlib.oidc.core.grants.implicit.OpenIDImplicitGrant.validate_authorization_request` | | Vulnerability class | Authorization bypass: a client's scope restriction is bypassed for OpenID Connect ID token issuance | | Verified against | `c529a61af40e3efe05286140e00fbdced07d7987` (v1.8.0). Earlier releases were not checked. | | API surface | Public API (`OpenIDImplicitGrant`, registered with `server.register_grant(...)`) | | Affected in default configuration | Yes. No non-default option is needed once `OpenIDImplicitGrant` is registered. Client metadata decides exposure: Authlib's standard `ClientMixin` checks response type and scope independently, so a client can be permitted `id_token` responses without being allowed the `openid` scope. | Summary `OpenIDImplicitGrant.validate_authorization_request()` first runs the…
Recommended action: Upgrade to 1.9.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
`OctKey.import_key()` carries the only guard that stops an asymmetric public key from being used as an HMAC secret in `authlib.jose`. That guard is `raw_key.startswith(POSSIBLE_UNSAFE_KEYS)` — anchored at byte 0 — while the loader that consumes the identical bytes on the asymmetric path (`cryptography.hazmat.primitives.serialization.load_pem_public_key` / `load_pem_x509_certificate`) skips anything before the `-----BEGIN` line. A PEM public key or X.509 certificate carrying one leading byte — a newline, a space, four spaces of indentation, a UTF-8 BOM, or a comment line — is therefore not recognised, falls through, and becomes the HMAC secret. An attacker holding only the issuer's public key then mints an `HS256` token with arbitrary claims that `jwt.decode()` accepts as authentic. This is an incomplete fix of CVE-2024-37568 / GHSA-5357-c2jx-v7qh. That advisory's fix is exactly this guard (`git log -S 'POSSIBLE_UNSAFE_KEYS' -- authlib/jose/rfc7518/oct_key.py`…
Recommended action: Upgrade to 1.9.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
`authlib.common.security.is_secure_transport()` is used throughout Authlib to enforce the OAuth 2.0 / OIDC requirement that endpoint and redirect URIs use TLS, with an RFC 8252 §7.3 exemption for loopback `http://` URIs. The check is implemented as a textual `str.startswith` prefix match, so a URL such as `http://localhost:80@evil.example/cb` — whose actual host is `evil.example` and whose scheme is plain `http` — is accepted as "secure". An attacker who can supply a URL to any of the sinks that rely on this check (OIDC RP-Initiated Logout dynamic client registration, RFC 8414 authorization-server metadata validation, error-redirect rendering) can smuggle a cleartext non-loopback URL past the TLS-required guard. This is a defense-in-depth / spec-conformance failure; severity is low. Details Affected versions: `authlib >= 0.13, <= 1.7.2` (all releases containing the loopback prefix exemption; verified against 1.7.2, the current latest) The vulnerable function, from…
Recommended action: Upgrade to 1.8.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Authlib (prior to 1.9.0) contains a signature verification bypass vulnerability. The JsonWebSignature.deserialize_json() method accepts a JSON Serialization JWS object and returns the payload as successfully verified without checking for a signature and without requiring a cryptographic key. Root cause `authlib/jose/rfc7515/jws.py`, read on the installed 1.8.0 artifact: ```python is_valid = True set before anything is checked for header_obj in obj["signatures"]: empty array means the body never runs jws_header, valid = self._validate_json_jws(...) if not valid: is_valid = False ... if is_valid: return rv returns the payload as verified ``` `is_valid` is initialised to `True` and only ever set to `False` from inside the loop. A JWS JSON Serialization object whose `signatures` array is empty iterates zero times, so the flag survives and the payload is returned as successfully verified. No key is consulted, because no signature is examined. Reproduction ```python import…
Recommended action: Upgrade to 1.9.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Authlib's OAuth 2.0 authorization endpoint can be turned into an unauthenticated open redirect when a request uses an unsupported responsetype and supplies an attacker-controlled redirecturi. The vulnerable behavior happens before client lookup and before any redirect URI validation. As a result, an attacker does not need a valid client registration, an authenticated user, or any prior state. A single request to the authorization endpoint is enough to obtain a 302 Location response to an arbitrary attacker-controlled URL. It was confirmed that the vulnerable code is present in tag v1.6.6 and in the current HEAD under test (68e6ab3fdfc71a328b1966bad5c6aba0f7d0c2e1, git describe: v1.6.6-104-g68e6ab3f). The issue was dynamically reproduced locally on the current HEAD. Details The root cause is that AuthorizationServer.getauthorizationgrant() copies the raw request redirecturi into an UnsupportedResponseTypeError before any client has been resolved and before any redirect URI…
Recommended action: Upgrade to 1.7.1 or 1.6.10 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
An unauthenticated open redirect in Authlib's OpenIDImplicitGrant and OpenIDHybridGrant authorization endpoint lets a remote attacker cause the authorization server to issue an HTTP 302 to an attacker-chosen URL by submitting an authorization request that omits the openid scope. Details Vulnerable code OpenIDImplicitGrant.validateauthorizationrequest in authlib/oidc/core/grants/implicit.py: OpenIDHybridGrant.validateauthorizationrequest in authlib/oidc/core/grants/hybrid.py shares the same pattern. Root cause Both methods perform the openid scope presence check before delegating to super().validateauthorizationrequest(), which is where AuthorizationEndpointMixin.validateauthorizationredirecturi validates the requested redirecturi against the client's checkredirecturi(...). The InvalidScopeError thrown by the scope check therefore carries attacker-controlled self.request.payload.redirecturi. OAuth2Error.call in authlib/oauth2/base.py renders any error with a non-empty…
Recommended action: Upgrade to 1.7.1 or 1.6.12 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
There is no CSRF protection on the cache feature on most integrations clients. Details In authlib.integrations.starletteclient.OAuth, no CSRF protection is set up when using the cache parameter. When not using the cache parameter, the use of SessionMiddleware ties the client to the auth state, preventing CSRF attacks. With the cache, there is no such mechanism. Other integratons have the same issue, it's not just starlette. The state parameter is taken from the callback URL and the state is fetched from the cache without checking that it is the same client calling the redirect endpoint as was the one that initiated the auth flow. This issue is documented in RFC 6749 section 10.12: https://datatracker.ietf.org/doc/html/rfc6749#section-10.12 PoC - Set up a Starlette integration with a cache - The attacker starts the auth flow up until before the callback URL is followed. - The attacked sends the redirect URL to the victim - The victim now completes the authorisation Impact This…
Recommended action: Upgrade to 1.6.11 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
1. Executive Summary A critical library-level vulnerability was identified in the Authlib Python library concerning the validation of OpenID Connect (OIDC) ID Tokens. Specifically, the internal hash verification logic (verifyhash) responsible for validating the athash (Access Token Hash) and chash (Authorization Code Hash) claims exhibits a fail-open behavior when encountering an unsupported or unknown cryptographic algorithm. This flaw allows an attacker to bypass mandatory integrity protections by supplying a forged ID Token with a deliberately unrecognized alg header parameter. The library intercepts the unsupported state and silently returns True (validation passed), inherently violating fundamental cryptographic design principles and direct OIDC specifications. --- 2. Technical Details & Root Cause The vulnerability resides within the verifyhash(signature, s, alg) function in authlib/oidc/core/claims.py: When an unsupported algorithm string (e.g., "XX999") is processed by the…
Recommended action: Upgrade to 1.6.9 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
1. Executive Summary A cryptographic padding oracle vulnerability was identified in the Authlib Python library concerning the implementation of the JSON Web Encryption (JWE) RSA15 key management algorithm. Authlib registers RSA15 in its default algorithm registry without requiring explicit opt-in, and actively destroys the constant-time Bleichenbacher mitigation that the underlying cryptography library implements correctly. When cryptography encounters an invalid PKCS#1 v1.5 padding, it returns a randomized byte string instead of raising an exception — the correct behavior per RFC 3218 §2.3.2. Authlib ignores this contract and raises ValueError('Invalid "cek" length') immediately after decryption, before reaching AES-GCM tag validation. This creates a clean, reliable Exception Oracle: - Invalid padding → cryptography returns random bytes → Authlib length check fails → ValueError: Invalid "cek" length - Valid padding, wrong MAC → decryption succeeds → length check passes → AES-GCM…
Recommended action: Upgrade to 1.6.9 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Summary A JWK Header Injection vulnerability in `authlib`'s JWS implementation allows an unauthenticated attacker to forge arbitrary JWT tokens that pass signature verification. When `key=None` is passed to any JWS deserialization function, the library extracts and uses the cryptographic key embedded in the attacker-controlled JWT `jwk` header field. An attacker can sign a token with their own private key, embed the matching public key in the header, and have the server accept the forged token as cryptographically valid — bypassing authentication and authorization entirely. This behavior violates RFC 7515 §4.1.3 and the validation algorithm defined in RFC 7515 §5.2. Details Vulnerable file: `authlib/jose/rfc7515/jws.py` Vulnerable method: `JsonWebSignature._prepare_algorithm_key()` Lines: 272–273 ```python elif key is None and "jwk" in header: key = header["jwk"] ← attacker-controlled key used for verification ``` When `key=None` is passed…
Recommended action: Upgrade to 1.6.9 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
After upgrading the library from 1.5.2 to 1.6.0 (and the latest 1.6.5) it was noticed that previous tests involving passing a malicious JWT containing alg: none and an empty signature was passing the signature verification step without any changes to the application code when a failure was expected. Details It was likely introduced in this commit: https://github.com/authlib/authlib/commit/a61c2acb807496e67f32051b5f1b1d5ccf8f0a75 PoC Output: Impact Users of the library are likely not aware that they now need to check the provided headers and disallow alg: none usage, it is not obvious from the release notes that any action needs to be taken. As a best-practice, the library should adopt a 'secure by default' stance and default to rejecting it and allow the application to provide an algorithm whitelist. Applications using this library for authentication or authorization may accept malicious, forged JWTs, leading to: - Authentication bypass - Privilege escalation - Unauthorized…
Recommended action: Upgrade to 1.6.7 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Security Advisory: Cache-Backed State Storage CSRF in Authlib The Security Labs team at Snyk has reported a security issue affecting Authlib, identified during a recent research project. The Snyk Security Labs team has identified a vulnerability that can result in a one-click account takeover in applications that utilize the Authlib library. Description Cache-backed state/request-token storage is not tied to the initiating user session, making CSRF possible for any attacker that possesses a valid state value (easily obtainable via an attacker-initiated authentication flow). When a cache is supplied to the OAuth client registry, FrameworkIntegration.setstatedata writes the entire state blob under state{app}{state}, and getstatedata disregards the caller's session entirely. [1][2] authlib/integrations/baseclient/frameworkintegration.py:12-41 Retrieval in authorizeaccesstoken therefore succeeds for whichever browser presents that opaque value, and the token exchange proceeds with the…
Recommended action: Upgrade to 1.6.6 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Authlib’s JWE zip=DEF path performs unbounded DEFLATE decompression. A very small ciphertext can expand into tens or hundreds of megabytes on decrypt, allowing an attacker who can supply decryptable tokens to exhaust memory and CPU and cause denial of service. Details - Affected component: Authlib JOSE, JWE zip=DEF (DEFLATE) support. - In authlib/authlib/jose/rfc7518/jwezips.py, DeflateZipAlgorithm.decompress calls zlib.decompress(s, -zlib.MAXWBITS) without a maximum output limit. This permits unbounded expansion of compressed payloads. - In the JWE decode flow (authlib/authlib/jose/rfc7516/jwe.py), when the protected header contains "zip": "DEF", the library routes the decrypted ciphertext into the decompress method and assigns the fully decompressed bytes to the plaintext field before returning it. No streaming limit or quota is applied. - Because DEFLATE achieves extremely high ratios on highly repetitive input, an attacker can craft a tiny zip=DEF ciphertext that inflates…
Recommended action: Upgrade to 1.6.5 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Authlib’s JOSE implementation accepts unbounded JWS/JWT header and signature segments. A remote attacker can craft a token whose base64url‑encoded header or signature spans hundreds of megabytes. During verification, Authlib decodes and parses the full input before it is rejected, driving CPU and memory consumption to hostile levels and enabling denial of service. Impact - Attack vector: unauthenticated network attacker submits a malicious JWS/JWT. - Effect: base64 decode + JSON/crypto processing of huge buffers pegs CPU and allocates large amounts of RAM; a single request can exhaust service capacity. - Observed behaviour: on a test host, the legacy code verified a 500 MB header, consuming ~4 GB RSS and ~9 s CPU before failing. - Severity: High. CVSS v3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (7.5). Affected Versions Authlib ≤ 1.6.3 (and earlier) when verifying JWS/JWT tokens. Later snapshots with 256 KB header/signature limits are not affected. Proof of concept Local demo…
Recommended action: Upgrade to 1.6.5 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Authlib’s JWS verification accepts tokens that declare unknown critical header parameters (crit), violating RFC 7515 “must‑understand” semantics. An attacker can craft a signed token with a critical header (for example, bork or cnf) that strict verifiers reject but Authlib accepts. In mixed‑language fleets, this enables split‑brain verification and can lead to policy bypass, replay, or privilege escalation. Affected Component and Versions - Library: Authlib (JWS verification) - API: authlib.jose.JsonWebSignature.deserializecompact(...) - Version tested: 1.6.3 - Configuration: Default; no allowlist or special handling for crit Details RFC 7515 (JWS) §4.1.11 defines crit as a “must‑understand” list: recipients MUST understand and enforce every header parameter listed in crit, otherwise they MUST reject the token. Security‑sensitive semantics such as token binding (e.g., cnf from RFC 7800) are often conveyed via crit. Observed behavior with Authlib 1.6.3: - When a compact JWS…
Recommended action: Upgrade to 1.6.4 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
lepture Authlib before 1.3.1 has algorithm confusion with asymmetric public keys. Unless an algorithm is specified in a jwt.decode call, HMAC verification is allowed with any asymmetric public key. (This is similar to CVE-2022-29217 and CVE-2024-33663.)
Recommended action: Upgrade to 1.3.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.