Skip to main content
Vulnerability Database/CVE-2026-53938

CVE-2026-53938: OpenIDC/cjose AES Key Wrap DOS Vulnerability

CVE-2026-53938 is a denial of service flaw in OpenIDC/cjose that allows attackers to trigger heap corruption through crafted JWE tokens. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-53938 Overview

CVE-2026-53938 is a heap buffer overflow [CWE-122] in OpenIDC/cjose, a C library implementing JSON Object Signing and Encryption (JOSE). Versions prior to 0.6.2.5 fail to validate the length of the attacker-supplied encrypted_key in the JWE decryption path when using AES Key Wrap algorithms (A128KW, A192KW, A256KW). A remote, unauthenticated attacker can submit a crafted JSON Web Encryption (JWE) token to any application that decrypts it with an AES-KW symmetric key. The unwrap operation copies attacker-controlled bytes into a fixed-size heap-allocated Content Encryption Key (CEK) buffer, corrupting adjacent heap memory.

Critical Impact

Pre-authentication heap corruption reachable through cjose_jwe_import() and cjose_jwe_decrypt(), leading to denial of service and potentially further memory-corruption impact depending on allocator behavior.

Affected Products

  • OpenIDC/cjose versions prior to 0.6.2.5
  • Applications that invoke cjose_jwe_import() or cjose_jwe_decrypt() on untrusted input
  • Downstream projects embedding cjose for JWE processing with AES Key Wrap algorithms

Discovery Timeline

  • 2026-09-09 - CVE-2026-53938 published to the National Vulnerability Database (NVD)
  • 2026-09-09 - Last updated in NVD database

Technical Details for CVE-2026-53938

Vulnerability Analysis

The defect resides in cjose's JWE decryption path for the AES Key Wrap key-management algorithms. When a JWE header specifies alg values of A128KW, A192KW, or A256KW, cjose invokes AES_unwrap_key() from OpenSSL to unwrap the JWE Encrypted Key into the pre-allocated jwe->cek buffer. The library does not verify that the length of the attacker-controlled encrypted_key matches the expected wrapped size before the unwrap call. AES_unwrap_key() writes bytes proportional to the input length, so an oversized encrypted_key produces an out-of-bounds write past the CEK buffer.

Because cjose_jwe_import() and cjose_jwe_decrypt() sit at pre-authentication entry points, applications typically expose them to arbitrary network input before any identity check. The result is a remote, unauthenticated heap corruption primitive.

Root Cause

The root cause is missing input validation on the length of the JWE Encrypted Key field. RFC 3394 specifies that an AES key-wrapped ciphertext is always the plaintext key length plus 8 bytes. cjose did not enforce this invariant before unwrap, allowing attacker-controlled writes into a fixed-size heap allocation.

Attack Vector

An attacker crafts a JWE token containing an AES-KW alg value and an oversized encrypted_key component. The attacker submits this token to any HTTP endpoint or message channel that calls cjose to decrypt JWEs with a symmetric key. Processing the token triggers the out-of-bounds heap write during unwrap.

c
         return false;
     }
 
+    // the wrapped key (RFC 3394) is always the plaintext CEK length plus 8 bytes;
+    // enforce this before calling AES_unwrap_key, which would otherwise copy the
+    // attacker-controlled encrypted_key into the fixed-size jwe->cek buffer
+    if (recipient->enc_key.raw_len != jwe->cek_len + 8)
+    {
+        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
+        return false;
+    }
+
     // AES unwrap the CEK in to jwe->cek
     int len = AES_unwrap_key(&akey, (const unsigned char *)NULL, jwe->cek, (const unsigned char *)recipient->enc_key.raw,
                              recipient->enc_key.raw_len);

Source: OpenIDC/cjose commit 8c51d24. The patch adds a strict length check that rejects any encrypted_key whose raw length is not exactly cek_len + 8 bytes, blocking the overflow before AES_unwrap_key() is invoked.

Detection Methods for CVE-2026-53938

Indicators of Compromise

  • Unexpected process crashes, SIGABRT, or SIGSEGV in services that parse JWEs with cjose linked in
  • Heap corruption reports from allocator instrumentation such as glibc mallocabort() messages or AddressSanitizer traces referencing AES_unwrap_key or jwe.c
  • Inbound requests containing JWEs whose alg header equals A128KW, A192KW, or A256KW with encrypted_key values that decode to unusual lengths

Detection Strategies

  • Inventory dependencies to identify software linking against cjose versions prior to 0.6.2.5, including OpenID Connect libraries such as mod_auth_openidc
  • Instrument non-production builds of cjose consumers with AddressSanitizer to catch out-of-bounds writes during fuzz testing of JWE inputs
  • Log JWE header parameters at ingress and flag AES Key Wrap algorithms if the application does not require them for legitimate use

Monitoring Recommendations

  • Monitor authentication and API gateways for anomalous crash rates correlated with JWE-bearing requests
  • Track base64url-decoded encrypted_key lengths and alert when values deviate from the RFC 3394 expected sizes of 24, 32, or 40 bytes
  • Enable core dump collection on services embedding cjose to support post-incident forensic analysis

How to Mitigate CVE-2026-53938

Immediate Actions Required

  • Upgrade cjose to version 0.6.2.5 or later across all systems that process untrusted JWEs
  • Audit application code paths that invoke cjose_jwe_import() or cjose_jwe_decrypt() and confirm they run behind rate limiting and input validation
  • Rebuild and redeploy any statically linked binaries that bundle vulnerable cjose versions

Patch Information

The fix is delivered in cjose 0.6.2.5. The upstream commit 8c51d245273583a658f24ef7b08ba22f848a34a5 enforces the RFC 3394 length invariant before calling AES_unwrap_key(). Refer to the GitHub Security Advisory GHSA-75r7-f5cv-g3wj for the full advisory text.

Workarounds

  • Reject the AES Key Wrap algorithms A128KW, A192KW, and A256KW at the application layer for JWEs originating from untrusted sources
  • Restrict accepted JWE alg values to an allowlist that excludes symmetric AES-KW variants where feasible
  • Place a validating proxy in front of vulnerable services to enforce maximum encrypted_key sizes consistent with RFC 3394
bash
# Example: pin the fixed version in a build manifest
# Debian/Ubuntu source build
git clone https://github.com/OpenIDC/cjose.git
cd cjose
git checkout 0.6.2.5
./configure && make && sudo make install

# Verify the installed version
pkg-config --modversion cjose

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.