CVE-2026-114616
Authlib accepts an empty HMAC key, allowing JWS/JWT signature forgery (HS256/HS384/HS512)
Authlib is a Python library which builds OAuth and OpenID Connect servers. Prior to 1.9.1, Authlib's OctKey.import_key() and HMAC signing and verification path accept zero-length key material. If an application's secret lookup can return an empty string or empty bytes, a remote attacker can compute the deterministic HS256, HS384, or HS512 signature for arbitrary token claims and have Authlib treat the token as authentic. This issue is fixed in version 1.9.1.
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 accepts an empty HMAC key, allowing JWS/JWT signature forgery (HS256/HS384/HS512)
Authlib is a Python library which builds OAuth and OpenID Connect servers. Prior to 1.9.1, Authlib's OctKey.import_key() and HMAC signing and verification path accept zero-length key material. If an application's secret lookup can return an empty string or empty bytes, a remote attacker can compute the deterministic HS256, HS384, or HS512 signature for arbitrary token claims and have Authlib treat the token as authentic. This issue is fixed in version 1.9.1.
- Record
CVE-2026-114616- 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-287, CWE-326, CWE-1391
- Updated
- 2026-11-02
EUVDEUVD-2026-108517
7.4
Authlib is a Python library which builds OAuth and OpenID Connect servers. Prior to 1.9.1, Authlib's OctKey.import_key() and HMAC signing and verification path accept zero-length key material. If an application's secret lookup can return an empty string or empty bytes, a remote attacker can compute the deterministic HS256, HS384, or HS512 signature for arbitrary token claims and have Authlib treat the token as authentic. This issue is fixed in version 1.9.1.
- Record
EUVD-2026-108517- 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-8m4g-j4wp-wgcg
7.4
Authlib accepts an empty HMAC key, allowing JWS/JWT signature forgery (HS256/HS384/HS512)
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 algorithm, and asymmetric-vs-symmetric confusion respectively; none of them rejects a zero-length oct key.
Affected versions
Authlib <= 1.7.2 (latest release 1.7.2, 2026-05-06). Confirmed present at the v1.7.2 release tag and on the current main HEAD. The affected code is in authlib/jose/rfc7518/oct_key.py and authlib/jose/rfc7518/jws_algs.py.
Root cause (exact code location, release tag v1.7.2)
- authlib/jose/rfc7518/oct_key.py, class OctKey:
- validate_raw_key is a type-only check:
return isinstance(key, bytes). An empty bytes object passes. - import_key rejects only keys whose material starts with known unsafe prefixes (
if raw_key.startswith(POSSIBLE_UNSAFE_KEYS): raise ValueError(...), i.e. PEM/SSH prefixes). Empty bytes do not match any unsafe prefix, so b'' is accepted. - get_op_key loads the raw key without validating its length.
- No check anywhere rejects a zero-length key, so an empty key b'' passes every gate.
- validate_raw_key is a type-only check:
- authlib/jose/rfc7518/jws_algs.py, class HMACAlgorithm:
- prepare_key:
return OctKey.import_key(raw_data). - sign / verify call key.get_op_key(...) then
hmac.new(op_key, msg, self.hash_alg)/hmac.compare_digest(...). With an empty op key this becomes hmac.new(b'', ...): a deterministic, publicly reproducible digest. There is no empty-key or minimum-length check.
- prepare_key:
Why this is a real signature bypass
An empty HMAC key makes the signature a public, deterministic function of the header and payload, so anyone can compute a valid signature and forge tokens. The realistic trigger matches the sibling CVEs: the deploying application sources the verification key from a place that can be empty at runtime, for example os.environ.get('JWT_SECRET', ''), a database/config column whose default is '', or a key-resolver that returns '' on a miss. Authlib is widely used to BUILD token verifiers (OAuth 2.0 resource servers, OIDC relying parties), and Authlib's own recent advisory history shows the JWS/JWT verify path is the live attack surface, so a key-resolution path that can yield '' is a realistic exposure.
Reproduction (prose, no weaponized exploit)
- In an application that uses Authlib to verify JWS/JWT, arrange for the verification key to be an empty value (e.g. an unset environment variable defaulted to '').
- An attacker constructs a token with header {alg: HS256} and an arbitrary payload, and computes the HS256 signature using an empty key (a value any party can reproduce because the key is empty).
- Authlib's HMAC verification accepts the token as validly signed, because OctKey.import_key did not reject the empty key and hmac.compare_digest matches the attacker-computable digest. The forged token is treated as authentic.
No live system was probed; the above describes the class. The vulnerable code path and the absent guard are confirmed by direct reading of the public source at the v1.7.2 tag and on current main.
Proof the fix is known-good (no novelty risk)
The same maintainer's newer JOSE library,…
- Record
GHSA-8m4g-j4wp-wgcg- 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-287, CWE-326, CWE-1391
- Updated
- 2026-11-02
NVD
7.4
Authlib is a Python library which builds OAuth and OpenID Connect servers. Prior to 1.9.1, Authlib's OctKey.import_key() and HMAC signing and verification path accept zero-length key material. If an application's secret lookup can return an empty string or empty bytes, a remote attacker can compute the deterministic HS256, HS384, or HS512 signature for arbitrary token claims and have Authlib treat the token as authentic. This issue is fixed in version 1.9.1.
- Record
CVE-2026-114616- 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-287, CWE-326, CWE-1391
- Updated
- 2026-11-02
OSV
7.4
Authlib accepts an empty HMAC key, allowing JWS/JWT signature forgery (HS256/HS384/HS512)
Authlib is a Python library which builds OAuth and OpenID Connect servers. Prior to 1.9.1, Authlib's OctKey.import_key() and HMAC signing and verification path accept zero-length key material. If an application's secret lookup can return an empty string or empty bytes, a remote attacker can compute the deterministic HS256, HS384, or HS512 signature for arbitrary token claims and have Authlib treat the token as authentic. This issue is fixed in version 1.9.1.
- Record
CVE-2026-114616- 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-1391, CWE-287, CWE-326
- Updated
- 2026-11-03
OSVDEBIAN-CVE-2026-114616
9.1
Authlib is a Python library which builds OAuth and OpenID Connect servers. Prior to 1.9.1, Authlib's OctKey.import_key() and HMAC signing and verification path accept zero-length key material. If an application's secret lookup can return an empty string or empty bytes, a remote attacker can compute the deterministic HS256, HS384, or HS512 signature for arbitrary token claims and have Authlib treat the token as authentic. This issue is fixed in version 1.9.1.
- Record
DEBIAN-CVE-2026-114616- 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-8m4g-j4wp-wgcg
7.4
Authlib accepts an empty HMAC key, allowing JWS/JWT signature forgery (HS256/HS384/HS512)
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 algorithm, and asymmetric-vs-symmetric confusion respectively; none of them rejects a zero-length oct key.
Affected versions
Authlib <= 1.7.2 (latest release 1.7.2, 2026-05-06). Confirmed present at the v1.7.2 release tag and on the current main HEAD. The affected code is in authlib/jose/rfc7518/oct_key.py and authlib/jose/rfc7518/jws_algs.py.
Root cause (exact code location, release tag v1.7.2)
- authlib/jose/rfc7518/oct_key.py, class OctKey:
- validate_raw_key is a type-only check:
return isinstance(key, bytes). An empty bytes object passes. - import_key rejects only keys whose material starts with known unsafe prefixes (
if raw_key.startswith(POSSIBLE_UNSAFE_KEYS): raise ValueError(...), i.e. PEM/SSH prefixes). Empty bytes do not match any unsafe prefix, so b'' is accepted. - get_op_key loads the raw key without validating its length.
- No check anywhere rejects a zero-length key, so an empty key b'' passes every gate.
- validate_raw_key is a type-only check:
- authlib/jose/rfc7518/jws_algs.py, class HMACAlgorithm:
- prepare_key:
return OctKey.import_key(raw_data). - sign / verify call key.get_op_key(...) then
hmac.new(op_key, msg, self.hash_alg)/hmac.compare_digest(...). With an empty op key this becomes hmac.new(b'', ...): a deterministic, publicly reproducible digest. There is no empty-key or minimum-length check.
- prepare_key:
Why this is a real signature bypass
An empty HMAC key makes the signature a public, deterministic function of the header and payload, so anyone can compute a valid signature and forge tokens. The realistic trigger matches the sibling CVEs: the deploying application sources the verification key from a place that can be empty at runtime, for example os.environ.get('JWT_SECRET', ''), a database/config column whose default is '', or a key-resolver that returns '' on a miss. Authlib is widely used to BUILD token verifiers (OAuth 2.0 resource servers, OIDC relying parties), and Authlib's own recent advisory history shows the JWS/JWT verify path is the live attack surface, so a key-resolution path that can yield '' is a realistic exposure.
Reproduction (prose, no weaponized exploit)
- In an application that uses Authlib to verify JWS/JWT, arrange for the verification key to be an empty value (e.g. an unset environment variable defaulted to '').
- An attacker constructs a token with header {alg: HS256} and an arbitrary payload, and computes the HS256 signature using an empty key (a value any party can reproduce because the key is empty).
- Authlib's HMAC verification accepts the token as validly signed, because OctKey.import_key did not reject the empty key and hmac.compare_digest matches the attacker-computable digest. The forged token is treated as authentic.
No live system was probed; the above describes the class. The vulnerable code path and the absent guard are confirmed by direct reading of the public source at the v1.7.2 tag and on current main.
Proof the fix is known-good (no novelty risk)
The same maintainer's newer JOSE library,…
- Record
GHSA-8m4g-j4wp-wgcg- 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-1391, CWE-287, CWE-326
- Updated
- 2026-11-02
OSVPYSEC-2026-4356
9.1
Authlib is a Python library which builds OAuth and OpenID Connect servers. Prior to 1.9.1, Authlib's OctKey.import_key() and HMAC signing and verification path accept zero-length key material. If an application's secret lookup can return an empty string or empty bytes, a remote attacker can compute the deterministic HS256, HS384, or HS512 signature for arbitrary token claims and have Authlib treat the token as authentic. This issue is fixed in version 1.9.1.
- Record
PYSEC-2026-4356- 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-114616
7.4
Authlib is a Python library which builds OAuth and OpenID Connect servers. Prior to 1.9.1, Authlib's OctKey.import_key() and HMAC signing and verification path accept zero-length key material. If an application's secret lookup can return an empty string or empty bytes, a remote attacker can compute the deterministic HS256, HS384, or HS512 signature for arbitrary token claims and have Authlib treat the token as authentic. This issue is fixed in version 1.9.1.
- Record
UBUNTU-CVE-2026-114616- 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 |
before 1.9.1 | 1.9.1 |
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 |
before 1.9.1, plus listed versions 0.10.100.110.120.12.1 Show 45 moreShow less0.130.140.14.10.14.20.14.30.150.15.10.15.20.15.30.15.40.15.50.15.60.1rc00.20.2.10.30.40.4.10.50.5.10.60.70.80.91.0.01.0.0a11.0.0a21.0.0b11.0.0b21.0.0rc11.0.11.1.01.2.01.2.11.3.01.3.11.3.21.4.01.4.11.5.01.5.11.5.21.6.01.6.11.6.10 |
1.9.1 |
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-114616 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.30%, the 22nd percentile. Fixed in authlib 1.9.1.
References
github.com/authlib/authlib/security/advisories/GHSA-8m4g-j4wp-wgcg
github.com/authlib/authlib/commit/4ff30db442c70e29486e1982cb0ad37c037f5f4b
github.com/authlib/authlib/releases/tag/v1.9.1
nvd.nist.gov/vuln/detail/CVE-2026-114616
github.com/advisories/GHSA-8m4g-j4wp-wgcg
github.com/CVEProject/cvelistV5/tree/main/cves/2026/114xxx/CVE-2026-114616.json
Show 14 moreShow less
security-tracker.debian.org/tracker/CVE-2026-114616
github.com/authlib/authlib
ubuntu.com/security/CVE-2026-114616
cve.org/CVERecord?id=CVE-2026-114616
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: 15 versions and the rest of 2 source descriptions. The JSON record has them.