CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-119283

CVE-2026-119283: Unbounded JWE Recipients Array Causes CPU Exhaustion in Authlib joserfc

Alon Barad
Alon Barad
Software Engineer

Oct 30, 2026·9 min read·2 visits

Executive Summary (TL;DR)

Authlib joserfc versions prior to 1.7.5 do not limit the size of the JWE General JSON Serialization recipients array and fail to short-circuit decryption loops when verify_all_recipients is disabled. Attackers can send a single JWE request containing thousands of RSA recipient blocks to trigger repeated private-key modular exponentiation, causing a high-impact denial of service via CPU exhaustion.

A resource consumption vulnerability exists in the Authlib joserfc Python library prior to version 1.7.5. When processing JSON Web Encryption (JWE) objects formatted using General JSON Serialization, the library fails to enforce an upper bound on the number of elements within the recipients array. An unauthenticated attacker can supply a JWE containing thousands of recipient entries targeting an RSA key management algorithm, forcing the server to perform an equivalent number of computationally expensive RSA private-key decryption operations per request and exhausting available CPU resources.

Vulnerability Overview

joserfc is a Python library developed by Authlib that implements Javascript Object Signing and Encryption (JOSE) standards, including RFC 7516 for JSON Web Encryption (JWE). Applications use joserfc to encrypt and decrypt structured tokens, API payloads, and OpenID Connect request objects. When an application exposes an endpoint that accepts JWE General JSON Serialization payloads, it relies on joserfc.jwe.decrypt_json() to parse the incoming JSON structure and decrypt the Content Encryption Key (CEK) using the server's configured cryptographic keys.

A resource management vulnerability tracked as CVE-2026-119283 (GHSA-jpxq-7h8p-2q76) affects joserfc versions prior to 1.7.5. Classified under CWE-400 (Uncontrolled Resource Consumption), the flaw resides in how joserfc._rfc7516 handles the recipients array within a JWE General JSON Serialization object. Unlike JWE Compact Serialization or Flattened JSON Serialization, which only support a single recipient, General JSON Serialization allows a payload to specify multiple recipients in a top-level JSON array so that multiple parties can independently decrypt the same underlying ciphertext.

Prior to version 1.7.5, joserfc ingested the recipients array without enforcing a maximum count limit and iterated over every entry during decryption. Furthermore, the internal decryption routine failed to halt iteration after a successful decryption even when the verify_all_recipients setting was set to False. Consequently, an unauthenticated remote attacker can submit a single HTTP request containing a JWE with thousands of recipient entries.

When the target endpoint uses an asymmetric RSA key-management algorithm (such as RSA-OAEP, RSA-OAEP-256, or RSA1_5), each entry in the recipients array forces the server to execute a distinct RSA private-key decryption operation. Because asymmetric private-key modular exponentiation is computationally expensive, processing a large array of recipients monopolizes worker threads and exhausts system CPU cycles, resulting in a denial of service without compromising data confidentiality or integrity.

Root Cause Analysis

Under RFC 7516 Section 7.2.1, a JWE using General JSON Serialization represents recipient-specific metadata inside a `

Code Analysis

The vulnerability was remediated in commit d6dc8df6c7609277e741069d3733e43996c1cd17 across three core files within the src/joserfc/_rfc7516/ module: registry.py, json.py, and message.py.

First, in src/joserfc/_rfc7516/registry.py, the maintainers introduced a configurable max_recipients parameter to the JWERegistry class with a default threshold of 16, alongside a validation method that raises ExceededSizeError when the threshold is breached:

class JWERegistry:
    # ... existing size constraints ...
    max_ciphertext_length: int = 65536  # 64KB
    max_auth_tag_length: int = 64
    #: max number of recipients in JWE General JSON Serialization
    max_recipients: int = 16
 
    def __init__(
        self,
        header_registry: HeaderRegistryDict | None = None,
        algorithms: Collection[str] | None = None,
        verify_all_recipients: bool = True,
        strict_check_header: bool = True,
        max_recipients: int | None = None,  # Added configurable override
    ):
        # ... initialization ...
        if max_recipients is not None:
            self.max_recipients = max_recipients
 
    def validate_recipient_count(self, recipients: Collection[t.Any]) -> None:
        # Enforce upper bound on recipient array length
        if len(recipients) > self.max_recipients:
            raise ExceededSizeError(f"Recipient count exceeds {self.max_recipients}.")

Second, in src/joserfc/_rfc7516/json.py, extract_general_json() was updated to invoke registry.validate_recipient_count(recipients) before extracting segments or iterating through recipient items:

def extract_general_json(data: GeneralJSONSerialization, registry: JWERegistry) -> GeneralJSONEncryption:
    protected_segment = data.get("protected")
    protected = json_b64decode(protected_segment)
 
    unprotected = data.get("unprotected")
    recipients = data["recipients"]
    # Validate array length immediately before allocating objects or decoding segments
    registry.validate_recipient_count(recipients)
    base64_segments, bytes_segments, aad = __extract_segments(data, registry)
 
    obj = GeneralJSONEncryption(protected, None, unprotected, aad)
    obj.base64_segments = base64_segments
    obj.bytes_segments = bytes_segments
    for item in recipients:
        recipient = __extract_recipient(obj, item, registry)
        obj.recipients.append(recipient)
    return obj

Third, in src/joserfc/_rfc7516/message.py, _perform_decrypt() was modified to move header validation inside the try block and add an else clause that breaks out of the recipient loop upon the first valid CEK recovery when verify_all_recipients is False:

    cek_set = set()
    for recipient in obj.recipients:
        try:
            headers = recipient.headers()
            registry.check_header(headers, True)
            alg = registry.get_alg(headers["alg"])
            cek = decrypt_recipient(alg, enc, recipient, tag)
            cek_set.add(cek)
        except (AssertionError, JoseError) as error:
            if registry.verify_all_recipients:
                raise error
        else:
            # Short-circuit after the first successful decryption if full verification is not required
            if not registry.verify_all_recipients:
                break
 
    if not cek_set:
        raise DecodeError("Invalid recipients")

> [!NOTE] > Assessment of Fix Completeness: The patch effectively bounds the maximum number of recipient entries to 16 by default and ensures early termination when verify_all_recipients=False. Note that verify_all_recipients defaults to True in JWERegistry. Consequently, an attacker can still force up to 16 RSA decryption operations per request under default settings if all 16 entries contain valid encrypted keys (or if the attacker sends 16 valid copies of a publicly encrypted CEK using the server's public RSA key). However, capping the amplification factor at 16x—and allowing operators to lower max_recipients and set verify_all_recipients=False—neutralizes unbounded single-request CPU exhaustion.

Exploitation

Exploiting CVE-2026-119283 does not require authentication or secret cryptographic material if the target endpoint exposes its RSA public key (for instance, via a standard .well-known/jwks.json endpoint) or even if the attacker submits malformed encrypted_key values when verify_all_recipients=False is configured on the server.

Consider the two server configurations prior to version 1.7.5:

  1. When verify_all_recipients=True (Default): If the attacker provides an invalid encrypted_key, the first recipient throws a JoseError and aborts the loop. However, because RSA is an asymmetric cryptosystem, an attacker who possesses the server's public RSA key (commonly published in JWKS endpoints for clients to encrypt tokens or request objects to the server) can generate a valid Content Encryption Key, encrypt it once or multiple times using the server's RSA public key (RSA-OAEP), and duplicate that valid recipient object 5,000 times inside the recipients array. Because every entry is cryptographically valid, no exception is raised, and _perform_decrypt() executes 5,000 full RSA private-key decryptions.
  2. When verify_all_recipients=False: The server suppresses JoseError exceptions during recipient decryption so that it can skip entries intended for other recipients. In this configuration, the attacker does not even need the server's public key to construct valid ciphertexts; any random byte string matching the RSA modulus length will undergo modular exponentiation before failing PKCS#1 v1.5 or OAEP padding validation, triggering a caught JoseError and continuing to the next recipient in the array.

The following proof-of-concept logic, adapted from the upstream regression test suite in tests/jwe/test_general.py, demonstrates how GeneralJSONEncryption constructs a multi-recipient payload that triggers unbounded iteration in versions < 1.7.5 while raising ExceededSizeError in version 1.7.5:

from joserfc import jwe
from joserfc.jwe import GeneralJSONEncryption, JWERegistry
from joserfc.jwk import RSAKey
from joserfc.errors import ExceededSizeError
 
# Generate a 2048-bit RSA key pair representing the server's key
rsa_key = RSAKey.generate_key(2048)
 
# Construct a JWE General JSON object
protected_header = {"enc": "A128CBC-HS256"}
obj = GeneralJSONEncryption(protected_header, b"test payload")
 
# Populate recipients beyond the 1.7.5 default limit (16)
# An attacker in the wild would scale this count into the hundreds or thousands
for _ in range(JWERegistry.max_recipients + 1):
    obj.add_recipient({"alg": "RSA-OAEP"}, rsa_key)
 
payload = jwe.encrypt_json(obj, None)
 
# In joserfc < 1.7.5: decrypt_json performs 17 RSA private-key decryptions
# In joserfc >= 1.7.5: raises ExceededSizeError immediately during JSON extraction
try:
    jwe.decrypt_json(payload, rsa_key)
except ExceededSizeError as err:
    print(f"Blocked by patch: {err}")

Impact Assessment

The primary impact of CVE-2026-119283 is high-severity availability degradation (Denial of Service). The vulnerability is scored at CVSS v3.1 7.5 (High) with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. Because the flaw is triggered prior to application-level authentication checks whenever JWE tokens are used as bearer credentials or encrypted request payloads, the Attack Vector is Network (AV:N), Attack Complexity is Low (AC:L), and Privileges Required is None (PR:N).

A single 2048-bit RSA private-key operation in Python (backed by OpenSSL via cryptography) typically takes between 0.5 and 1.5 milliseconds of dedicated CPU time, while a 4096-bit RSA operation takes roughly 4 to 10 milliseconds. By packing 2,000 recipient entries into a single JSON request body (which requires only ~700 KB of JSON text), a single HTTP request can occupy a CPU core for 1 to 20 seconds.

In Python web deployments using synchronous worker models (such as Gunicorn with sync workers) or asynchronous event loops (such as Uvicorn/FastAPI where synchronous CPU-bound calls block the main event loop thread), a low-bandwidth stream of requests is sufficient to saturate all worker processes. Legitimate requests queue behind the blocked workers and eventually fail with HTTP 502/504 gateway timeouts.

There is no direct impact on confidentiality (C:N) or integrity (I:N). The vulnerability does not leak timing information sufficient for padding oracle attacks beyond normal processing, nor does it bypass cryptographic verification. As of the latest threat intelligence telemetry, CVE-2026-119283 is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog and holds a low EPSS score of 0.00229 (13.73rd percentile).

Remediation

Organizations and developers utilizing joserfc should upgrade to version 1.7.5 or later immediately. Version 1.7.5 enforces a default limit of 16 recipients on JWE General JSON Serialization payloads and short-circuits recipient decryption loops when verify_all_recipients is set to False.

pip install --upgrade "joserfc>=1.7.5"

For applications that do not require multi-recipient JWE General JSON Serialization—or where the expected number of recipients is strictly known to be small—developers should explicitly configure a custom JWERegistry with a reduced max_recipients threshold and disable verify_all_recipients so that decryption halts as soon as the server's own recipient entry is decrypted:

from joserfc import jwe
from joserfc.jwe import JWERegistry
 
# Restrict to at most 2 recipients and stop after first valid decryption
custom_registry = JWERegistry(
    max_recipients=2,
    verify_all_recipients=False
)
 
decrypted_obj = jwe.decrypt_json(payload, server_private_key, registry=custom_registry)

furthermore, if the application only expects standard single-recipient tokens in Compact Serialization (header.encrypted_key.iv.ciphertext.tag), ensure the codebase calls joserfc.jwe.decrypt_compact() rather than joserfc.jwe.decrypt_json(), which completely avoids the JSON serialization parser.

If an immediate library upgrade is not feasible, deploy the following compensating controls at the reverse proxy, WAF, or API gateway layer:

  • JSON Schema Inspection: Configure the WAF or API gateway to inspect incoming JSON bodies and reject payloads where the top-level recipients array contains more than a small number of elements (e.g., 5 or 16).
  • HTTP Request Body Size Limits: Restrict the maximum allowed HTTP request body size on authentication and token endpoints to prevent large recipient arrays from reaching the application server.

Official Patches

AuthlibGitHub Security Advisory GHSA-jpxq-7h8p-2q76
AuthlibUpstream patch commit in authlib/joserfc
Authlibjoserfc 1.7.5 release notes and tag

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Probability
0.23%
Top 86% most exploited

Affected Systems

Authlib joserfc Python library (< 1.7.5)

Affected Versions Detail

Product
Affected Versions
Fixed Version
joserfc
Authlib
< 1.7.51.7.5
AttributeDetail
Vulnerability ClassCWE-400: Uncontrolled Resource Consumption
Attack VectorNetwork (Unauthenticated JWE General JSON payload)
CVSS v3.1 Score7.5 High (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
EPSS Score0.23% (13.73rd percentile)
Security ImpactDenial of Service via CPU exhaustion from repeated RSA decryptions
Affected Functionjoserfc.jwe.decrypt_json() / _perform_decrypt()
Patched Versionjoserfc 1.7.5
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-400
Uncontrolled Resource Consumption

The software does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.

Vulnerability Timeline

Upstream fix committed to authlib/joserfc repository (d6dc8df6c7609277e741069d3733e43996c1cd17)
2026-08-28
joserfc version 1.7.5 released to PyPI
2026-08-29
GitHub Security Advisory GHSA-jpxq-7h8p-2q76 and CVE-2026-119283 published
2026-10-29

References & Sources

  • [1]GitHub Security Advisory: GHSA-jpxq-7h8p-2q76
  • [2]Authlib joserfc Patch Commit d6dc8df6c7609277e741069d3733e43996c1cd17
  • [3]Authlib joserfc Release 1.7.5
  • [4]NVD - CVE-2026-119283
  • [5]CVE.org Record: CVE-2026-119283
  • [6]CVEList V5 JSON Record: CVE-2026-119283
  • [7]Shodan CVEDB: CVE-2026-119283

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•13 minutes ago•GHSA-FGXM-5HVV-X4VH
5.3

GHSA-fgxm-5hvv-x4vh: Private Repository Enumeration via Go Module Discovery and HTTP Response Discrepancies in Soft Serve

Charmbracelet Soft Serve versions 0.5.0 through 0.12.2 contain an authorization bypass and observable response discrepancy vulnerability in the HTTP Git server. Remote attackers can determine the existence, exact names, and clone URLs of private repositories by issuing crafted Go remote import path discovery requests (?go-get=1) or by observing differential HTTP status codes across Git Smart HTTP, Dumb HTTP, and Git LFS endpoints.

Alon Barad
Alon Barad
0 views•12 min read
•about 1 hour ago•GHSA-F3FJ-9625-RV3M
5.9

GHSA-f3fj-9625-rv3m: Race Condition in Soft Serve Repository Cache Invalidation

A Time-of-Check to Time-of-Use (TOCTOU) race condition in Charmbracelet Soft Serve versions 0.6.0 through 0.12.2 allows unauthenticated users to retain read access to repositories after their visibility is changed from public to private. The flaw stems from premature cache invalidation in the SetPrivate method prior to committing the visibility update to the underlying database. Concurrent read requests arriving during the database transaction window repopulate the non-expiring in-memory LRU cache with stale public metadata, bypassing access controls across HTTP, SSH, and Git protocols until the server process is restarted.

Alon Barad
Alon Barad
3 views•10 min read
•about 3 hours ago•CVE-2026-119284
6.9

CVE-2026-119284: Uncontrolled Resource Consumption in joserfc Compact Deserialization

CVE-2026-119284 (GHSA-9pg5-8c7x-5hfx) is an uncontrolled resource consumption vulnerability (CWE-400) in the compact serialization deserialization routines of joserfc prior to version 1.7.6. The library enforced individual segment size limits only after invoking Python's bytes.split(b'.') on untrusted input tokens. By sending oversized compact JWS or JWE tokens, an unauthenticated remote attacker can force the Python interpreter to duplicate and allocate memory for every segment before size validation executes, resulting in memory exhaustion and an Endpoint Denial of Service (DoS).

Amit Schendel
Amit Schendel
7 views•10 min read
•about 10 hours ago•GHSA-C33X-VCV4-VG3G
2.1

GHSA-c33x-vcv4-vg3g: Missing Slot Identifier Validation in Cedar Policy Language JSON Template Parser Causes Panic and Authorization Divergence

An improper input validation vulnerability (CWE-20) exists in the Entity Syntax Tree (EST) JSON deserialization component of the Cedar Policy Language (`cedar-policy` and `@cedar-policy/cedar-wasm`). When parsing JSON-formatted policy templates that define `is ... in` scope constraints on `principal` or `resource`, the parser used wildcard pattern matching that ignored the provided slot identifier (`?principal` or `?resource`). This omission allows malformed JSON templates to bypass initial deserialization validation, resulting in either a runtime panic during template linking or inverted slot bindings that alter authorization outcomes.

Amit Schendel
Amit Schendel
7 views•10 min read
•about 11 hours ago•GHSA-W9X9-J56R-H98R
8.2

GHSA-w9x9-j56r-h98r: Unauthenticated Confused Deputy Proxy in @eeacms/volto-chatbot

The @eeacms/volto-chatbot package for Plone Volto contains an unauthenticated confused deputy vulnerability (CWE-862) in versions 2.0.3 and earlier. The package registers Express middleware on wildcard proxy routes (`**/_v1_da/**` and `**/_v1_ha/**`) without verifying client authentication or restricting target endpoints. When processing incoming HTTP requests, the middleware automatically attaches server-side administrative credentials before forwarding the requests to upstream Danswer (Onyx) or Halloumi (LLMGW) API servers. This allows unauthenticated network attackers to execute arbitrary administrative API calls against the backend infrastructure.

Amit Schendel
Amit Schendel
6 views•8 min read
•about 13 hours ago•CVE-2026-9705
6.5

CVE-2026-9705: Registration Access Token Authorization Bypass in Keycloak Dynamic Client Registration

CVE-2026-9705 is an insufficient session expiration and authorization bypass vulnerability in Keycloak and Red Hat build of Keycloak. The vulnerability occurs in the OAuth 2.0 Dynamic Client Registration Management Protocol implementation, where the authentication handler fails to verify whether a target client is enabled before accepting requests authenticated with a previously issued Registration Access Token (RAT). Consequently, an actor possessing a valid RAT for an administratively disabled client can query, update, and re-enable the client configuration, restoring revoked access to realm resources.

Amit Schendel
Amit Schendel
8 views•10 min read