joserfc has Possible Uncontrolled Resource Consumption Vulnerability Triggered by Logging Arbitrarily Large JWT Token Payloads
Description
joserfc is a Python library that provides an implementation of several JSON Object Signing and Encryption (JOSE) standards. In versions from 1.3.3 to before 1.3.5 and from 1.4.0 to before 1.4.2, the ExceededSizeError exception messages are embedded with non-decoded JWT token parts and may cause Python logging to record an arbitrarily large, forged JWT payload. In situations where a misconfigured — or entirely absent — production-grade web server sits in front of a Python web application, an attacker may be able to send arbitrarily large bearer tokens in the HTTP request headers. When this occurs, Python logging or diagnostic tools (e.g., Sentry) may end up processing extremely large log messages containing the full JWT header during the joserfc.jwt.decode() operation. The same behavior also appears when validating claims and signature payload sizes, as the library raises joserfc.errors.ExceededSizeError() with the full payload embedded in the exception message. Since the payload is already fully loaded into memory at this stage, the library cannot prevent or reject it. This issue has been patched in versions 1.3.5 and 1.4.2.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
In joserfc library embeds raw JWT payloads in ExceededSizeError exceptions, which can cause uncontrolled resource consumption when logged.
Vulnerability
Overview
In joserfc versions 1.3.3 to before 1.3.5 and 1.4.0 to before 1.4.2, the ExceededSizeError exception messages include the raw, non-decoded JWT token parts (header, payload, or signature) that triggered the size check [1]. This means that when a JWT exceeds configured size limits, the library raises an exception whose message contains the full oversized token data.
Attack
Vector
An attacker can send an arbitrarily large bearer token in an HTTP request header to a Python web application that uses joserfc for JWT decoding [1]. If the application does not have a production-grade reverse proxy (e.g., nginx) or proper header size limits enforced by the web server (e.g., uvicorn/h11), the oversized JWT reaches the Python application. During joserfc.jwt.decode(), the library loads the entire payload into memory and then raises ExceededSizeError with the full payload embedded in the exception message [1].
Impact
When the exception is logged by Python logging frameworks or forwarded to diagnostic tools like Sentry, the extremely large log message can cause uncontrolled resource consumption (CPU, memory, disk I/O) [1]. This can lead to denial of service, as the logging system may become overwhelmed processing the oversized message. The library cannot prevent this because the payload is already fully loaded into memory before the size check occurs [1].
Mitigation
The issue has been patched in joserfc versions 1.3.5 and 1.4.2 [1]. The fix removes the raw value from the ExceededSizeError exception message, as shown in the commit diffs [3][4]. Users should update to the patched versions and also ensure that a reverse proxy or web server enforces appropriate header size limits to prevent oversized tokens from reaching the application [1].
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
joserfcPyPI | >= 1.3.3, < 1.3.5 | 1.3.5 |
joserfcPyPI | >= 1.4.0, < 1.4.2 | 1.4.2 |
Affected products
2- authlib/joserfcv5Range: >= 1.3.3, < 1.3.5
Patches
263932f169d92fix: remove raw value from ExceededSizeError
2 files changed · +8 −8
src/joserfc/_rfc7515/registry.py+3 −3 modified@@ -101,15 +101,15 @@ def check_header(self, header: Header) -> None: def validate_header_size(self, header: bytes) -> None: if header and len(header) > self.max_header_length: - raise ExceededSizeError(f"Header size of '{header!r}' exceeds {self.max_header_length} bytes.") + raise ExceededSizeError(f"Header size exceeds {self.max_header_length} bytes.") def validate_payload_size(self, payload: bytes) -> None: if payload and len(payload) > self.max_payload_length: - raise ExceededSizeError(f"Payload size of '{payload!r}' exceeds {self.max_payload_length} bytes.") + raise ExceededSizeError(f"Payload size exceeds {self.max_payload_length} bytes.") def validate_signature_size(self, signature: bytes) -> None: if len(signature) > self.max_signature_length: - raise ExceededSizeError(f"Signature of '{signature!r}' exceeds {self.max_signature_length} bytes.") + raise ExceededSizeError(f"Signature of exceeds {self.max_signature_length} bytes.") @classmethod def guess_alg(cls, key: Any, strategy: Strategy) -> str | None:
src/joserfc/_rfc7516/registry.py+5 −5 modified@@ -102,25 +102,25 @@ def check_header(self, header: Header, check_more: bool = False) -> None: def validate_protected_header_size(self, header: bytes) -> None: if header and len(header) > self.max_protected_header_length: - raise ExceededSizeError(f"Header size of '{header!r}' exceeds {self.max_protected_header_length} bytes.") + raise ExceededSizeError(f"Header size exceeds {self.max_protected_header_length} bytes.") def validate_encrypted_key_size(self, ek: bytes) -> None: if ek and len(ek) > self.max_encrypted_key_length: - raise ExceededSizeError(f"Encrypted key size of '{ek!r}' exceeds {self.max_encrypted_key_length} bytes.") + raise ExceededSizeError(f"Encrypted key size exceeds {self.max_encrypted_key_length} bytes.") def validate_initialization_vector_size(self, iv: bytes) -> None: if iv and len(iv) > self.max_initialization_vector_length: raise ExceededSizeError( - f"Initialization vector size of '{iv!r}' exceeds {self.max_initialization_vector_length} bytes." + f"Initialization vector size exceeds {self.max_initialization_vector_length} bytes." ) def validate_ciphertext_size(self, ciphertext: bytes) -> None: if ciphertext and len(ciphertext) > self.max_ciphertext_length: - raise ExceededSizeError(f"Ciphertext size of '{ciphertext!r}' exceeds {self.max_ciphertext_length} bytes.") + raise ExceededSizeError(f"Ciphertext size exceeds {self.max_ciphertext_length} bytes.") def validate_auth_tag_size(self, tag: bytes) -> None: if tag and len(tag) > self.max_auth_tag_length: - raise ExceededSizeError(f"Auth tag size of '{tag!r}' exceeds {self.max_auth_tag_length} bytes.") + raise ExceededSizeError(f"Auth tag size exceeds {self.max_auth_tag_length} bytes.") def get_alg(self, name: str) -> JWEAlgModel: """Get the allowed ("alg") algorithm instance of the given name.
673c8743fd06fix: remove raw value from ExceededSizeError
2 files changed · +8 −8
src/joserfc/_rfc7515/registry.py+3 −3 modified@@ -101,15 +101,15 @@ def check_header(self, header: Header) -> None: def validate_header_size(self, header: bytes) -> None: if header and len(header) > self.max_header_length: - raise ExceededSizeError(f"Header size of '{header!r}' exceeds {self.max_header_length} bytes.") + raise ExceededSizeError(f"Header size exceeds {self.max_header_length} bytes.") def validate_payload_size(self, payload: bytes) -> None: if payload and len(payload) > self.max_payload_length: - raise ExceededSizeError(f"Payload size of '{payload!r}' exceeds {self.max_payload_length} bytes.") + raise ExceededSizeError(f"Payload size exceeds {self.max_payload_length} bytes.") def validate_signature_size(self, signature: bytes) -> None: if len(signature) > self.max_signature_length: - raise ExceededSizeError(f"Signature of '{signature!r}' exceeds {self.max_signature_length} bytes.") + raise ExceededSizeError(f"Signature of exceeds {self.max_signature_length} bytes.") @classmethod def guess_alg(cls, key: Any, strategy: Strategy) -> str | None:
src/joserfc/_rfc7516/registry.py+5 −5 modified@@ -102,25 +102,25 @@ def check_header(self, header: Header, check_more: bool = False) -> None: def validate_protected_header_size(self, header: bytes) -> None: if header and len(header) > self.max_protected_header_length: - raise ExceededSizeError(f"Header size of '{header!r}' exceeds {self.max_protected_header_length} bytes.") + raise ExceededSizeError(f"Header size exceeds {self.max_protected_header_length} bytes.") def validate_encrypted_key_size(self, ek: bytes) -> None: if ek and len(ek) > self.max_encrypted_key_length: - raise ExceededSizeError(f"Encrypted key size of '{ek!r}' exceeds {self.max_encrypted_key_length} bytes.") + raise ExceededSizeError(f"Encrypted key size exceeds {self.max_encrypted_key_length} bytes.") def validate_initialization_vector_size(self, iv: bytes) -> None: if iv and len(iv) > self.max_initialization_vector_length: raise ExceededSizeError( - f"Initialization vector size of '{iv!r}' exceeds {self.max_initialization_vector_length} bytes." + f"Initialization vector size exceeds {self.max_initialization_vector_length} bytes." ) def validate_ciphertext_size(self, ciphertext: bytes) -> None: if ciphertext and len(ciphertext) > self.max_ciphertext_length: - raise ExceededSizeError(f"Ciphertext size of '{ciphertext!r}' exceeds {self.max_ciphertext_length} bytes.") + raise ExceededSizeError(f"Ciphertext size exceeds {self.max_ciphertext_length} bytes.") def validate_auth_tag_size(self, tag: bytes) -> None: if tag and len(tag) > self.max_auth_tag_length: - raise ExceededSizeError(f"Auth tag size of '{tag!r}' exceeds {self.max_auth_tag_length} bytes.") + raise ExceededSizeError(f"Auth tag size exceeds {self.max_auth_tag_length} bytes.") def get_alg(self, name: str) -> JWEAlgModel: """Get the allowed ("alg") algorithm instance of the given name.
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-frfh-8v73-gjg4ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-65015ghsaADVISORY
- github.com/authlib/joserfc/commit/63932f169d924caffafa761af2122b82059017f7ghsax_refsource_MISCWEB
- github.com/authlib/joserfc/commit/673c8743fd0605b0e1de6452be6cba75f44e466bghsax_refsource_MISCWEB
- github.com/authlib/joserfc/releases/tag/1.3.5ghsax_refsource_MISCWEB
- github.com/authlib/joserfc/releases/tag/1.4.2ghsax_refsource_MISCWEB
- github.com/authlib/joserfc/security/advisories/GHSA-frfh-8v73-gjg4ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.