CVE-2026-28490 Overview
CVE-2026-28490 is a cryptographic padding oracle vulnerability affecting the Authlib Python library, which is widely used for building OAuth and OpenID Connect servers. The vulnerability exists in the implementation of the JSON Web Encryption (JWE) RSA1_5 key management algorithm. Prior to version 1.6.9, Authlib registered RSA1_5 in its default algorithm registry without requiring explicit opt-in, and critically, the implementation actively destroyed the constant-time Bleichenbacher mitigation that the underlying cryptography library implements correctly.
This padding oracle attack vector allows network-based attackers to potentially decrypt JWE tokens by observing timing differences in error responses, enabling them to recover sensitive encrypted data without possessing the private key.
Critical Impact
Attackers can exploit this padding oracle vulnerability to decrypt JWE tokens and extract sensitive authentication data, potentially compromising OAuth/OpenID Connect implementations that rely on Authlib for cryptographic operations.
Affected Products
- Authlib versions prior to 1.6.9
- Applications using Authlib's JWE implementation with RSA1_5 algorithm
- OAuth and OpenID Connect servers built with vulnerable Authlib versions
Discovery Timeline
- 2026-03-16 - CVE CVE-2026-28490 published to NVD
- 2026-03-17 - Last updated in NVD database
Technical Details for CVE-2026-28490
Vulnerability Analysis
This vulnerability is classified under CWE-203 (Observable Discrepancy), which relates to information exposure through timing or behavioral differences. The core issue lies in how Authlib handles the RSA1_5 algorithm for JWE decryption.
The RSA PKCS#1 v1.5 encryption scheme is inherently vulnerable to Bleichenbacher attacks (also known as "million message attack" or padding oracle attacks). Modern cryptographic libraries like Python's cryptography package implement constant-time mitigations to prevent attackers from distinguishing between valid and invalid padding through timing analysis. However, Authlib's implementation inadvertently destroyed these protections by introducing observable timing differences in its error handling paths.
The attack requires network access and the ability to send crafted JWE tokens to a vulnerable application. By analyzing the response times for different malformed tokens, an attacker can progressively recover the plaintext content of encrypted tokens.
Root Cause
The root cause of CVE-2026-28490 is twofold:
Unsafe Default Configuration: The RSA1_5 algorithm was registered in Authlib's default algorithm registry without requiring explicit opt-in, exposing users to a deprecated and vulnerable algorithm by default.
Broken Constant-Time Operations: The implementation's error handling code paths introduced timing variations that leaked information about the validity of PKCS#1 v1.5 padding, negating the constant-time protections provided by the underlying cryptography library.
Attack Vector
The attack is network-based and does not require authentication or user interaction. An attacker with the ability to intercept or observe JWE tokens can:
- Capture an encrypted JWE token destined for a vulnerable Authlib-based application
- Send modified versions of the token with manipulated ciphertext bytes
- Measure response timing differences to determine padding validity
- Use the Bleichenbacher adaptive chosen-ciphertext attack to progressively recover the session key
- Decrypt the original token contents to access sensitive data
The patch introduces a deprecated attribute to algorithm definitions and modifies the algorithm selection logic to reject deprecated algorithms by default:
raise MissingAlgorithmError()
alg = header["alg"]
- if self._algorithms is not None and alg not in self._algorithms:
- raise UnsupportedAlgorithmError()
if alg not in self.ALGORITHMS_REGISTRY:
raise UnsupportedAlgorithmError()
algorithm = self.ALGORITHMS_REGISTRY[alg]
+ if self._algorithms is None:
+ if algorithm.deprecated:
+ raise UnsupportedAlgorithmError()
+ elif alg not in self._algorithms:
+ raise UnsupportedAlgorithmError()
+
if callable(key):
key = key(header, payload)
key = algorithm.prepare_key(key)
Source: GitHub Commit Details
The algorithm model was also updated to support deprecation marking:
name = None
description = None
+ deprecated = False
algorithm_type = "JWS"
algorithm_location = "alg"
Source: GitHub Commit Details
Detection Methods for CVE-2026-28490
Indicators of Compromise
- Unusual patterns of repeated JWE token submissions with slight variations in ciphertext
- Elevated error rates in OAuth/OIDC token validation endpoints
- Network traffic analysis showing systematic probing of token endpoints with timing measurement characteristics
- Log entries showing multiple UnsupportedAlgorithmError or decryption failures from single source IPs
Detection Strategies
- Monitor application logs for anomalous patterns of JWE decryption failures from single sources
- Implement rate limiting on token validation endpoints to detect and throttle potential oracle attacks
- Review dependency manifests (requirements.txt, Pipfile, pyproject.toml) for Authlib versions prior to 1.6.9
- Use software composition analysis (SCA) tools to identify vulnerable Authlib installations across your environment
Monitoring Recommendations
- Enable detailed logging for all JWE token processing operations including timing metrics
- Configure alerting for statistically significant deviations in token validation response times
- Monitor for requests containing the RSA1_5 algorithm identifier in JWE headers
- Implement network-level monitoring for patterns consistent with adaptive chosen-ciphertext attacks
How to Mitigate CVE-2026-28490
Immediate Actions Required
- Upgrade Authlib to version 1.6.9 or later immediately using pip install authlib>=1.6.9
- Audit your codebase for explicit use of the RSA1_5 algorithm and migrate to RSA-OAEP or RSA-OAEP-256
- Review existing JWE tokens and consider re-encrypting sensitive data after patching
- Rotate any cryptographic keys that may have been used with the vulnerable RSA1_5 implementation
Patch Information
The vulnerability has been patched in Authlib version 1.6.9. The fix introduces a deprecation mechanism for unsafe algorithms and ensures RSA1_5 is no longer available in the default algorithm registry. Users who explicitly require RSA1_5 for legacy compatibility must now opt-in deliberately.
Patch details are available in the GitHub Commit and the GitHub Security Advisory.
Workarounds
- If immediate upgrade is not possible, explicitly configure Authlib to exclude RSA1_5 from the allowed algorithms list
- Implement additional rate limiting and anomaly detection on token validation endpoints
- Consider using Web Application Firewalls (WAF) to detect and block potential padding oracle attack patterns
- Temporarily disable JWE functionality if RSA1_5 is the only supported key management algorithm in your deployment
# Configuration example
# Upgrade Authlib to patched version
pip install --upgrade authlib>=1.6.9
# Verify installed version
pip show authlib | grep Version
# Search for RSA1_5 usage in your codebase
grep -r "RSA1_5" --include="*.py" .
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

