Mar 16, 2026·7 min read·2 visits
A padding oracle vulnerability in Authlib's JWE RSA1_5 implementation allows remote attackers to decrypt intercepted JWE tokens. The issue stems from improper length validation of the decrypted CEK, which bypasses underlying cryptographic mitigations. Version 1.6.9 fixes the issue by disabling RSA1_5 by default.
Authlib versions prior to 1.6.9 contain a cryptographic padding oracle vulnerability in the JSON Web Encryption (JWE) RSA1_5 implementation. By mishandling the length check of decrypted Content Encryption Keys (CEK), the library exposes an exception oracle that allows unauthenticated remote attackers to decrypt intercepted JWE tokens via a Bleichenbacher attack.
CVE-2026-28490 describes a critical padding oracle vulnerability within Authlib, a widely deployed Python library utilized for building OAuth and OpenID Connect infrastructure. The flaw specifically resides in the implementation of the JSON Web Encryption (JWE) RSA1_5 key management algorithm. This algorithm is responsible for securely transmitting the Content Encryption Key (CEK) used to encrypt the token payload.
In standard JWE operations, the RSAES-PKCS1-v1_5 scheme encrypts the CEK. Modern cryptographic implementations recognize the inherent risks of PKCS#1 v1.5 padding and implement specific constant-time mitigations to prevent oracle attacks. The vulnerability in Authlib occurs because the library's internal key validation logic introduces an observable discrepancy, effectively neutralizing the mitigations provided by the underlying cryptographic primitives.
The resulting vulnerability is classified as CWE-203 (Observable Discrepancy) and CWE-327 (Use of a Broken or Risky Cryptographic Algorithm). Remote, unauthenticated attackers can leverage this observable discrepancy to perform a Bleichenbacher padding oracle attack. Successful exploitation allows the attacker to systematically decrypt the CEK and access the sensitive contents of intercepted JWE tokens.
The fundamental root cause of CVE-2026-28490 lies in how Authlib handles the results of the initial RSA decryption phase during JWE unwrapping. A classic Bleichenbacher padding oracle attack targets PKCS#1 v1.5 padding by observing whether a server accepts or rejects ciphertexts based on padding validity. To prevent this, cryptographic providers like Python's cryptography library employ a specific mitigation strategy. Upon encountering invalid padding, the provider does not raise an error but instead returns a randomized byte string matching the RSA modulus size.
Authlib's vulnerability surfaces immediately after receiving this decrypted output in the unwrap method located in authlib/jose/rfc7518/jwe_algs.py. The library performs a strict length check on the decrypted CEK, comparing it against the expected length for the negotiated symmetric algorithm. For standard configurations like A128GCM, the expected CEK length is exactly 16 bytes.
When the cryptography backend processes a token with invalid PKCS#1 v1.5 padding, it returns a large randomized string, typically 256 bytes for a 2048-bit RSA key. The Authlib length validation logic subsequently evaluates this 256-byte string against the expected 16-byte length. This check predictably fails, triggering a distinct ValueError exception.
The generation of this specific ValueError acts as an exception oracle. The attacker can differentiate between a ciphertext that failed PKCS#1 v1.5 padding validation and a ciphertext that possessed valid padding but failed subsequent symmetric tag validation. This precise binary feedback is the core requirement for executing a Bleichenbacher attack.
The observable discrepancy is explicitly visible in the unwrapping logic where the ValueError is raised. The codebase trusts the output of the decryption operation and immediately applies conditional logic based on its length. The following block conceptualizes the vulnerable pattern identified in the library prior to version 1.6.9.
# Vulnerable Logic (Conceptual)
decrypted_cek = private_key.decrypt(encrypted_cek, padding.PKCS1v15())
if len(decrypted_cek) != expected_len:
raise ValueError("Invalid cek length")The fix implemented in commit 48b345f29f6c459f11c6a40162b6c0b742ef2e22 takes a decisive architectural approach. Rather than attempting to implement complex constant-time length validation in native Python, the maintainers opted to deprecate and disable the vulnerable RSA1_5 algorithm by default. The patch introduces a deprecated flag to the JWSAlgorithm and JWEAlgorithmBase models.
# authlib/jose/rfc7516/jwe.py
def get_header_alg(self, header):
# ...
alg = header["alg"]
if alg not in self.ALG_REGISTRY:
raise UnsupportedAlgorithmError()
instance = self.ALG_REGISTRY[alg]
# If no explicit whitelist is provided, block deprecated algorithms
if self._algorithms is None:
if instance.deprecated:
raise UnsupportedAlgorithmError()
elif alg not in self._algorithms:
raise UnsupportedAlgorithmError()
return instanceThe modified algorithm selection logic explicitly raises an UnsupportedAlgorithmError if the requested algorithm is marked as deprecated and the user has not provided an explicit whitelist. While this resolves the vulnerability for default deployments, the underlying discrepancy remains in the codebase. Applications that manually whitelist RSA1_5 bypass this protection and reintroduce the oracle vulnerability.
Exploitation of CVE-2026-28490 requires the attacker to have network access to the target Authlib server and the ability to submit JWE tokens for processing. Authentication is generally not a prerequisite, as the vulnerable decryption routine occurs prior to identity validation or signature verification of the token payload. The attacker initiates the exploitation sequence by capturing a valid, encrypted JWE token destined for the target system.
The attacker then performs the initial setup for a Bleichenbacher attack. They mathematically mutate the encrypted CEK segment of the intercepted JWE token and submit the modified token to the application endpoint. The attacker meticulously records the server's HTTP response code, response time, and any error messages returned.
During the observation phase, the attacker relies entirely on the exception oracle. A ValueError or a corresponding 500 Internal Server Error indicates the PKCS#1 v1.5 padding was structurally invalid. Alternatively, a different error, such as an InvalidTag exception or a generic decryption failure, indicates the padding was mathematically valid but the decrypted symmetric key was incorrect.
By systematically analyzing the server's binary responses across tens of thousands of requests, the attacker iteratively narrows the mathematical space containing the plaintext CEK. Once the complete CEK is recovered, the attacker uses it to execute the standard symmetric decryption phase, successfully extracting the confidential JWE payload.
Successful exploitation of CVE-2026-28490 results in a complete loss of confidentiality for the data encapsulated within targeted JWE tokens. Depending on the application's specific implementation, JWE tokens frequently transport highly sensitive information. This payload often includes authenticated identity claims, administrative session identifiers, embedded access tokens, or proprietary business data.
The vulnerability is assessed with a CVSS v4.0 base score of 8.3 HIGH. The vector string CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N emphasizes the remote, unauthenticated nature of the attack (AV:N, PR:N) and the severe impact on data confidentiality (VC:H). The high attack complexity metric (AC:H) correctly reflects the substantial request volume and precise statistical analysis required to execute a Bleichenbacher oracle successfully.
While the primary impact is focused on confidentiality, data integrity may be indirectly affected in specific token architectures (VI:L). If the compromised token utilizes a symmetric signing scheme bound to the compromised CEK, the attacker may gain the ability to forge valid tokens. However, in standard asymmetric OAuth and OIDC deployments, the attacker achieves data disclosure without direct write access.
The definitive remediation for CVE-2026-28490 is to update the Authlib dependency to version 1.6.9 or later. This release permanently marks the RSA1_5 algorithm as deprecated and explicitly removes it from the default algorithm processing pipeline. System administrators must ensure the package update propagates through all deployment environments and container images.
Developers must transition application architectures away from PKCS#1 v1.5 padding. Modern deployments should mandate secure key management algorithms such as RSA-OAEP, RSA-OAEP-256, or Elliptic Curve alternatives like ECDH-ES. These algorithms are fully supported natively by Authlib and provide robust mathematical protection against padding oracle side-channels.
For systems strictly requiring legacy RSA1_5 compatibility, operators must explicitly whitelist the algorithm within the Authlib configuration. Organizations taking this high-risk path must deploy aggressive compensating controls at the application perimeter. Specifically, robust rate limiting and strict WAF anomaly detection must be implemented to identify and block the high-volume request patterns indicative of a padding oracle probing cycle.
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
authlib Authlib | < 1.6.9 | 1.6.9 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-203, CWE-327 |
| Attack Vector | Network |
| CVSS Base Score | 8.3 |
| Authentication Required | None |
| Exploit Status | Theoretical / No public PoC |
| Confidentiality Impact | High |
The system produces different responses based on the validity of cryptographic padding, enabling an oracle attack.