CVE-2026-53939 Overview
CVE-2026-53939 is a cryptographic flaw in OpenIDC cjose, a C library implementing JSON Object Signing and Encryption (JOSE). In versions 0.6.1 through 0.6.2.5, cjose generates an all-zero content encryption key (CEK) when producing a JSON Web Encryption (JWE) object using any AES-CBC-HMAC content-encryption algorithm (A128CBC-HS256, A192CBC-HS384, or A256CBC-HS512) combined with a key-management algorithm that expects the library to create a fresh CEK. Because the CEK is a fixed, publicly known value, any party who intercepts the JWE can decrypt the plaintext and forge or modify content. The issue is fixed in version 0.6.2.6 and is classified under [CWE-321: Use of Hard-coded Cryptographic Key].
Critical Impact
Any JWE produced with an affected cjose version and AES-CBC-HMAC content encryption can be decrypted and tampered with by any observer, breaking both confidentiality and integrity.
Affected Products
- OpenIDC cjose version 0.6.1
- OpenIDC cjose versions 0.6.2 through 0.6.2.5
- Applications embedding cjose for JWE with A128CBC-HS256, A192CBC-HS384, or A256CBC-HS512
Discovery Timeline
- 2026-09-09 - CVE-2026-53939 published to the National Vulnerability Database (NVD)
- 2026-09-09 - Last updated in NVD database
Technical Details for CVE-2026-53939
Vulnerability Analysis
The defect lives in _cjose_jwe_set_cek_aes_cbc() inside src/jwe.c. When a caller does not supply a JSON Web Key (JWK), the function must allocate a buffer for the CEK and populate it with cryptographically random bytes drawn from OpenSSL's RAND_bytes. Instead, the pre-patch code inverted the random flag passed to _cjose_jwe_malloc, so the allocator zero-filled the buffer rather than randomizing it. Every JWE produced with an AES-CBC-HMAC enc value therefore used a CEK of 0x00 bytes, matching the required key length of 32, 48, or 64 bytes.
Both AES-CBC encryption and HMAC authentication in the JWE construction depend on this CEK. Once the key is a known constant, any recipient of the JWE can derive the AES key and HMAC key, decrypt the ciphertext, and produce a valid authentication tag over attacker-chosen plaintext. The encrypted_key value transmitted in the JWE is unrelated to security in this state, which is why the regression test in 0.6.2.6 asserts that two encryptions produce different encrypted_key outputs.
Root Cause
The root cause is a hard-coded cryptographic key created by an inverted boolean argument controlling random-fill behavior of the CEK buffer. The buffer was allocated with zero-fill rather than random-fill, producing a fixed, publicly derivable key.
Attack Vector
An attacker who obtains any affected JWE, for example by observing network traffic, reading logs, or accessing storage, can reconstruct the CEK offline. No credentials, user interaction, or privileged access are required. The attacker can then decrypt the payload and reissue a modified JWE with a correct authentication tag, defeating both confidentiality and integrity guarantees of the AES-CBC-HMAC construction.
if (strcmp(enc, CJOSE_HDR_ENC_A256CBC_HS512) == 0)
keysize = 64;
+ // if no JWK is provided, generate a random key
if (NULL == jwk)
{
- // allocate memory for the CEK and fill with random bytes or 0's
_cjose_release_cek(&jwe->cek, jwe->cek_len);
- if (!_cjose_jwe_malloc(keysize, !random, &jwe->cek, err))
+ if (!_cjose_jwe_malloc(keysize, random, &jwe->cek, err))
{
return false;
}
// Source: https://github.com/OpenIDC/cjose/commit/2a6e5bd969fa20059fb00913fb9f57d77ea6a4d9
// The patch removes the boolean inversion so the CEK buffer is filled with RAND_bytes output.
Detection Methods for CVE-2026-53939
Indicators of Compromise
- JWE tokens produced by affected cjose versions where the recovered CEK is all 0x00 bytes across independent encryptions.
- Application dependency manifests referencing cjose versions 0.6.1 through 0.6.2.5.
- Repeated identical encrypted_key values across otherwise distinct JWEs issued by the same service.
Detection Strategies
- Inventory build systems and container images for the libcjose shared object and pin the version string against the vulnerable range.
- Instrument JWE-issuing services to log the enc header and detect combinations of A128CBC-HS256, A192CBC-HS384, or A256CBC-HS512 with key-management algorithms that request a library-generated CEK.
- Attempt offline decryption of captured JWEs using an all-zero CEK during red-team validation to confirm exposure.
Monitoring Recommendations
- Alert on outbound tokens whose header algorithm pair matches the vulnerable combination until upgrade is confirmed.
- Track deployment telemetry for services still linking against cjose<= 0.6.2.5 after the patch window.
- Review authentication and session logs for token replay or tampering that could indicate exploitation of previously issued JWEs.
How to Mitigate CVE-2026-53939
Immediate Actions Required
- Upgrade all deployments of cjose to version 0.6.2.6 or later and rebuild dependent applications.
- Treat any data previously encrypted with the affected algorithm pair as compromised, re-encrypt it, and rotate any secrets it protected.
- Invalidate active sessions or tokens issued as JWEs during the vulnerable window.
Patch Information
The fix landed in commit 2a6e5bd969fa20059fb00913fb9f57d77ea6a4d9 and is included in release cjose v0.6.2.6. Details are documented in GitHub Security Advisory GHSA-f6wf-pqg3-6wqq. The change ensures _cjose_jwe_set_cek_aes_cbc() fills the CEK from RAND_bytes, and a regression test asserts distinct encrypted_key values across successive encryptions for each AES-CBC-HMAC variant.
Workarounds
- Switch the enc value to an AES-GCM variant (A128GCM, A192GCM, or A256GCM), which is unaffected by the defect.
- Use alg=dir with a caller-supplied CEK sourced from a vetted random source instead of letting cjose generate the CEK.
- Route JWE encryption through a different, non-affected JOSE library until the upgrade to 0.6.2.6 is deployed.
# Verify the installed cjose version and upgrade
pkg-config --modversion libcjose
git clone https://github.com/OpenIDC/cjose.git
cd cjose && git checkout v0.6.2.6
./configure && make && sudo make install
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

