CVE-2026-114615
Authlib incomplete algorithm-confusion fix permits HMAC forgery with prefixed public keys
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 1.3.1 until 1.9.0, OctKey.import_key() checks asymmetric-key markers only at byte zero while Authlib's PEM loaders accept leading whitespace, comments, or a byte-order mark. In deployments that use the documented mixed algorithm registry and already configure verification with PEM or certificate bytes containing such a prefix, an unauthenticated attacker who knows those same public-key bytes can use them as an HMAC secret and forge HS256 tokens with arbitrary identity or authorization claims. This is a bypass of the remediation for CVE-2024-37568. The module-level jwt object reaches OctKey.import_key() in authlib/jose/rfc7518/oct_key.py, where POSSIBLE_UNSAFE_KEYS fails to identify prefixed asymmetric key material. This issue is fixed in version 1.9.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.4
Authlib incomplete algorithm-confusion fix permits HMAC forgery with prefixed public keys
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 1.3.1 until 1.9.0, OctKey.import_key() checks asymmetric-key markers only at byte zero while Authlib's PEM loaders accept leading whitespace, comments, or a byte-order mark. In deployments that use the documented mixed algorithm registry and already configure verification with PEM or certificate bytes containing such a prefix, an unauthenticated attacker who knows those same public-key bytes can use them as an HMAC secret and forge HS256 tokens with arbitrary identity or authorization claims. This is a bypass of the remediation for CVE-2024-37568. The module-level jwt object reaches OctKey.import_key() in authlib/jose/rfc7518/oct_key.py, where POSSIBLE_UNSAFE_KEYS fails to identify prefixed asymmetric key material. This issue is fixed in version 1.9.0.
- Record
CVE-2026-114615- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-184, CWE-347
- Updated
- 2026-11-02
EUVDEUVD-2026-108514
7.4
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 1.3.1 until 1.9.0, OctKey.import_key() checks asymmetric-key markers only at byte zero while Authlib's PEM loaders accept leading whitespace, comments, or a byte-order mark. In deployments that use the documented mixed algorithm registry and already configure verification with PEM or certificate bytes containing such a prefix, an unauthenticated attacker who knows those same public-key bytes can use them as an HMAC secret and forge HS256 tokens with arbitrary identity or authorization claims. This is a bypass of the remediation for CVE-2024-37568. The module-level jwt object reaches OctKey.import_key() in authlib/jose/rfc7518/oct_key.py, where POSSIBLE_UNSAFE_KEYS fails to identify prefixed asymmetric key material. This issue is fixed in version 1.9.0.
- Record
EUVD-2026-108514- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-7vr2-2fgp-9w7p
7.4
Authlib incomplete algorithm-confusion fix permits HMAC forgery with prefixed public keys
Summary
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 returns a single
commit, 3bea812 "fix: prevent OctKey to import ssh/rsa/pem keys", referencing issue #654), and the
original attack works again unchanged whenever the stored PEM does not start at offset 0.
Reproduced end-to-end on 1.8.0, the newest release (published 2026-08-30), and on origin/main
(c529a61), with cryptography 50.0.2.
Preconditions
Both are deployment properties; neither is attacker-controlled at request time, and the attacker needs no secret and no user interaction.
-
The relying party uses the documented module-level
jwtobject.from authlib.jose import jwtis built atauthlib/jose/__init__.py:55-72with the full list["HS256","HS384","HS512","RS256",...,"EdDSA"], andJsonWebToken.decode(authlib/jose/rfc7519/jwt.py:80) exposes noalgorithmsparameter, so a caller of the documented object has no way to narrow it. This is the first code sample indocs/jose/jwt.rst:21-31.This hazard is already documented:
docs/jose/jwt.rst:73-79says "This decoding method is insecure. By defaultjwt.decodeparses the alg header. This allows symmetric macs and asymmetric signatures.", anddocs/jose/jwt.rst:94-98says "You should never combine symmetric (HS) and asymmetric (RS, ES, PS) signature schemes." The point of this report is not that the mixed list exists — it is that theoct_key.py:81backstop shipped for precisely that documented hazard does not hold. -
The verification key is passed as PEM/certificate text whose bytes do not begin at offset 0 with
-----BEGIN. Each of the following forms was confirmed to forge, and each also still verifies a genuine RS256/ES256 token with the identical bytes, so nothing in the deployment looks broken:- one leading newline — what a triple-quoted Python literal produces
- one leading space
- four-space indentation — an indented YAML/JSON/TOML config block
- a UTF-8 BOM — a Windows-editor artifact
- a leading comment line
- all of the above applied to an X.509
CERTIFICATEPEM instead of aPUBLIC KEYPEM
A raw DER SPKI blob also bypasses the guard, but DER cannot be used for genuine asymmetric verification through this path, so I exclude it as a non-deployable configuration and mention it only as further evidence of the recogniser/loader gap.
Details
authlib/jose/rfc7518/oct_key.py:10-17
POSSIBLE_UNSAFE_KEYS = (
b"-----BEGIN ",
b"---- BEGIN ",
b"ssh-rsa ",
b"ssh-dss ",
b"ssh-ed25519 ",
b"ecdsa-sha2-",
)
authlib/jose/rfc7518/oct_key.py:78-84
raw_key = to_bytes(raw)
# security check
if raw_key.startswith(POSSIBLE_UNSAFE_KEYS):
raise ValueError("This key may not be safe to import")
key = cls(raw_key=raw_key, options=options)
bytes.startswith is anchored. The loader on the asymmetric path is not:
authlib/jose/rfc7517/_cryptography_key.py:22-29 calls load_pem_public_key /…
- Record
GHSA-7vr2-2fgp-9w7p- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-184, CWE-347
- Updated
- 2026-11-02
NVD
7.4
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 1.3.1 until 1.9.0, OctKey.import_key() checks asymmetric-key markers only at byte zero while Authlib's PEM loaders accept leading whitespace, comments, or a byte-order mark. In deployments that use the documented mixed algorithm registry and already configure verification with PEM or certificate bytes containing such a prefix, an unauthenticated attacker who knows those same public-key bytes can use them as an HMAC secret and forge HS256 tokens with arbitrary identity or authorization claims. This is a bypass of the remediation for CVE-2024-37568. The module-level jwt object reaches OctKey.import_key() in authlib/jose/rfc7518/oct_key.py, where POSSIBLE_UNSAFE_KEYS fails to identify prefixed asymmetric key material. This issue is fixed in version 1.9.0.
- Record
CVE-2026-114615- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-184, CWE-347
- Updated
- 2026-11-02
OSV
7.4
Authlib incomplete algorithm-confusion fix permits HMAC forgery with prefixed public keys
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 1.3.1 until 1.9.0, OctKey.import_key() checks asymmetric-key markers only at byte zero while Authlib's PEM loaders accept leading whitespace, comments, or a byte-order mark. In deployments that use the documented mixed algorithm registry and already configure verification with PEM or certificate bytes containing such a prefix, an unauthenticated attacker who knows those same public-key bytes can use them as an HMAC secret and forge HS256 tokens with arbitrary identity or authorization claims. This is a bypass of the remediation for CVE-2024-37568. The module-level jwt object reaches OctKey.import_key() in authlib/jose/rfc7518/oct_key.py, where POSSIBLE_UNSAFE_KEYS fails to identify prefixed asymmetric key material. This issue is fixed in version 1.9.0.
- Record
CVE-2026-114615- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-184, CWE-347
- Updated
- 2026-11-03
OSVDEBIAN-CVE-2026-114615
9.1
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 1.3.1 until 1.9.0, OctKey.import_key() checks asymmetric-key markers only at byte zero while Authlib's PEM loaders accept leading whitespace, comments, or a byte-order mark. In deployments that use the documented mixed algorithm registry and already configure verification with PEM or certificate bytes containing such a prefix, an unauthenticated attacker who knows those same public-key bytes can use them as an HMAC secret and forge HS256 tokens with arbitrary identity or authorization claims. This is a bypass of the remediation for CVE-2024-37568. The module-level jwt object reaches OctKey.import_key() in authlib/jose/rfc7518/oct_key.py, where POSSIBLE_UNSAFE_KEYS fails to identify prefixed asymmetric key material. This issue is fixed in version 1.9.0.
- Record
DEBIAN-CVE-2026-114615- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
Show 4 moreShow less
OSVGHSA-7vr2-2fgp-9w7p
7.4
Authlib incomplete algorithm-confusion fix permits HMAC forgery with prefixed public keys
Summary
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 returns a single
commit, 3bea812 "fix: prevent OctKey to import ssh/rsa/pem keys", referencing issue #654), and the
original attack works again unchanged whenever the stored PEM does not start at offset 0.
Reproduced end-to-end on 1.8.0, the newest release (published 2026-08-30), and on origin/main
(c529a61), with cryptography 50.0.2.
Preconditions
Both are deployment properties; neither is attacker-controlled at request time, and the attacker needs no secret and no user interaction.
-
The relying party uses the documented module-level
jwtobject.from authlib.jose import jwtis built atauthlib/jose/__init__.py:55-72with the full list["HS256","HS384","HS512","RS256",...,"EdDSA"], andJsonWebToken.decode(authlib/jose/rfc7519/jwt.py:80) exposes noalgorithmsparameter, so a caller of the documented object has no way to narrow it. This is the first code sample indocs/jose/jwt.rst:21-31.This hazard is already documented:
docs/jose/jwt.rst:73-79says "This decoding method is insecure. By defaultjwt.decodeparses the alg header. This allows symmetric macs and asymmetric signatures.", anddocs/jose/jwt.rst:94-98says "You should never combine symmetric (HS) and asymmetric (RS, ES, PS) signature schemes." The point of this report is not that the mixed list exists — it is that theoct_key.py:81backstop shipped for precisely that documented hazard does not hold. -
The verification key is passed as PEM/certificate text whose bytes do not begin at offset 0 with
-----BEGIN. Each of the following forms was confirmed to forge, and each also still verifies a genuine RS256/ES256 token with the identical bytes, so nothing in the deployment looks broken:- one leading newline — what a triple-quoted Python literal produces
- one leading space
- four-space indentation — an indented YAML/JSON/TOML config block
- a UTF-8 BOM — a Windows-editor artifact
- a leading comment line
- all of the above applied to an X.509
CERTIFICATEPEM instead of aPUBLIC KEYPEM
A raw DER SPKI blob also bypasses the guard, but DER cannot be used for genuine asymmetric verification through this path, so I exclude it as a non-deployable configuration and mention it only as further evidence of the recogniser/loader gap.
Details
authlib/jose/rfc7518/oct_key.py:10-17
POSSIBLE_UNSAFE_KEYS = (
b"-----BEGIN ",
b"---- BEGIN ",
b"ssh-rsa ",
b"ssh-dss ",
b"ssh-ed25519 ",
b"ecdsa-sha2-",
)
authlib/jose/rfc7518/oct_key.py:78-84
raw_key = to_bytes(raw)
# security check
if raw_key.startswith(POSSIBLE_UNSAFE_KEYS):
raise ValueError("This key may not be safe to import")
key = cls(raw_key=raw_key, options=options)
bytes.startswith is anchored. The loader on the asymmetric path is not:
authlib/jose/rfc7517/_cryptography_key.py:22-29 calls load_pem_public_key /…
- Record
GHSA-7vr2-2fgp-9w7p- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-184, CWE-347
- Updated
- 2026-11-02
OSVPYSEC-2026-4355
9.1
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 1.3.1 until 1.9.0, OctKey.import_key() checks asymmetric-key markers only at byte zero while Authlib's PEM loaders accept leading whitespace, comments, or a byte-order mark. In deployments that use the documented mixed algorithm registry and already configure verification with PEM or certificate bytes containing such a prefix, an unauthenticated attacker who knows those same public-key bytes can use them as an HMAC secret and forge HS256 tokens with arbitrary identity or authorization claims. This is a bypass of the remediation for CVE-2024-37568. The module-level jwt object reaches OctKey.import_key() in authlib/jose/rfc7518/oct_key.py, where POSSIBLE_UNSAFE_KEYS fails to identify prefixed asymmetric key material. This issue is fixed in version 1.9.0.
- Record
PYSEC-2026-4355- CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-114615
7.4
Authlib is a Python library which builds OAuth and OpenID Connect servers. From 1.3.1 until 1.9.0, OctKey.import_key() checks asymmetric-key markers only at byte zero while Authlib's PEM loaders accept leading whitespace, comments, or a byte-order mark. In deployments that use the documented mixed algorithm registry and already configure verification with PEM or certificate bytes containing such a prefix, an unauthenticated attacker who knows those same public-key bytes can use them as an HMAC secret and forge HS256 tokens with arbitrary identity or authorization claims. This is a bypass of the remediation for CVE-2024-37568. The module-level jwt object reaches OctKey.import_key() in authlib/jose/rfc7518/oct_key.py, where POSSIBLE_UNSAFE_KEYS fails to identify prefixed asymmetric key material. This issue is fixed in version 1.9.0.
- Record
UBUNTU-CVE-2026-114615- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - CVSS 3.1
- 9.1 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
OSVopenSUSE-SU-2026:12390-1 No score
python313-Authlib-1.9.1-1.1 on GA media
These are all security issues fixed in the python313-Authlib-1.9.1-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:12390-1- Updated
- 2026-11-03
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
authlibPyPI |
1.3.1 to 1.8.0 | 1.9.0 |
python-authlibDebian:12 |
All versions, plus listed versions 1.2.0-11.2.0-1+deb12u11.2.0-1+deb12u21.2.1-11.3.0-1 Show 23 moreShow less1.3.0-21.3.0-31.3.1-11.3.2-11.3.2-21.4.0-11.4.1-11.5.0-11.5.1-11.5.2-11.6.0-11.6.1-11.6.3-11.6.4-11.6.5-11.6.6-11.6.7-11.6.8-11.6.9-11.7.0-11.7.2-11.7.2-21.9.1-1 |
None known |
python-authlibDebian:13 |
All versions, plus listed versions 1.6.0-11.6.0-1+deb13u11.6.1-11.6.3-11.6.4-1 Show 9 moreShow less1.6.5-11.6.6-11.6.7-11.6.8-11.6.9-11.7.0-11.7.2-11.7.2-21.9.1-1 |
None known |
python-authlibDebian:14 |
before 1.9.1-1, plus listed versions 1.6.0-11.6.1-11.6.3-11.6.4-11.6.5-1 Show 7 moreShow less1.6.6-11.6.7-11.6.8-11.6.9-11.7.0-11.7.2-11.7.2-2 |
1.9.1-1 |
authlibPyPI |
1.3.1 up to 1.9.0, plus listed versions 1.3.21.4.01.4.11.5.01.5.1 Show 18 moreShow less1.5.21.6.01.6.11.6.101.6.111.6.121.6.21.6.31.6.41.6.51.6.61.6.71.6.81.6.91.7.01.7.11.7.21.8.0 |
1.9.0 |
python-authlibUbuntu:Pro:22.04:LTS |
All versions, plus listed versions 0.15.4-10.15.5-10.15.5-1ubuntu0.1~esm10.15.5-1ubuntu0.1~esm2 |
None known |
python-authlibUbuntu:Pro:24.04:LTS |
All versions, plus listed versions 1.2.1-11.3.0-11.3.0-1ubuntu0.1~esm11.3.0-1ubuntu0.1~esm2 |
None known |
python-authlibUbuntu:26.10 |
All versions, plus listed versions 1.6.7-11.7.2-11.7.2-2 |
None known |
python-authlibUbuntu:Pro:26.04:LTS |
All versions, plus listed versions 1.6.0-11.6.5-11.6.6-11.6.7-11.6.7-1ubuntu0.1~esm1 |
None known |
python-AuthlibopenSUSE:Tumbleweed From an advisory covering 10 CVEs |
before 1.9.1-1.1 | 1.9.1-1.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | ||
| affected, aliases, facts, references | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-114615 is a high vulnerability (CVSS 7.4) in Authlib, published October 22, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.21%, the 11th percentile. Fixed in authlib 1.9.0.
References
github.com/authlib/authlib/security/advisories/GHSA-7vr2-2fgp-9w7p
github.com/authlib/authlib/pull/945
github.com/authlib/authlib/commit/e3bd41cb29dcfee434453b135ffb487884baeedf
github.com/authlib/authlib/releases/tag/v1.9.0
nvd.nist.gov/vuln/detail/CVE-2026-114615
github.com/advisories/GHSA-7vr2-2fgp-9w7p
Show 15 moreShow less
github.com/CVEProject/cvelistV5/tree/main/cves/2026/114xxx/CVE-2026-114615.json
security-tracker.debian.org/tracker/CVE-2026-114615
github.com/authlib/authlib
ubuntu.com/security/CVE-2026-114615
cve.org/CVERecord?id=CVE-2026-114615
suse.com/security/cve/CVE-2025-62706
suse.com/security/cve/CVE-2026-114614
suse.com/security/cve/CVE-2026-114615
suse.com/security/cve/CVE-2026-114616
suse.com/security/cve/CVE-2026-114617
suse.com/security/cve/CVE-2026-114618
suse.com/security/cve/CVE-2026-114619
suse.com/security/cve/CVE-2026-116672
suse.com/security/cve/CVE-2026-41425
suse.com/security/cve/CVE-2026-96760
Left out here: the rest of 2 source descriptions. The JSON record has them.