A cryptographic padding oracle vulnerability was identified in the Authlib Python library
concerning the implementation of the JSON Web Encryption (JWE) RSA1_5 key management
algorithm. Authlib registers RSA1_5 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:
cryptography returns random bytes → Authlib length check fails
→ ValueError: Invalid "cek" lengthInvalidTagThis oracle is active by default in every Authlib installation without any special configuration by the developer or the attacker. The three most widely used Python web frameworks — Flask, Django, and FastAPI — all expose distinguishable HTTP responses for these two exception classes in their default configurations, requiring no additional setup to exploit.
Empirically confirmed on authlib 1.6.8 + cryptography 46.0.5:
[PADDING INVALIDO] ValueError: Invalid "cek" length
[PADDING VALIDO/MAC] InvalidTag
File: authlib/jose/rfc7518/jwe_algs.py
def unwrap(self, enc_alg, ek, headers, key):
op_key = key.get_op_key("unwrapKey")
# cryptography implements Bleichenbacher mitigation here:
# on invalid padding it returns random bytes instead of raising.
# Empirically confirmed: returns 84 bytes for a 2048-bit key....
1.6.9Exploitability
AV:NAC:HAT:PPR:NUI:NVulnerable System
VC:HVI:LVA:NSubsequent System
SC:NSI:NSA:N8.3/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