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



GHSA-6VVH-PXR4-25R7

GHSA-6vvh-pxr4-25r7: Cryptographic Integrity Degradation in JWT Framework ChaCha20-Poly1305 Key Encryption

Amit Schendel
Amit Schendel
Senior Security Researcher

Jun 19, 2026·7 min read·4 visits

Executive Summary (TL;DR)

The PHP JWT Framework fails to store and verify the Poly1305 authentication tag for experimental ChaCha20-Poly1305 key encryption. This degrades the algorithm to an unauthenticated stream cipher, making the encrypted key malleable to bit-flipping attacks.

An implementation flaw in the experimental Chacha20Poly1305 key-encryption algorithm within the PHP JWT Framework (web-token/jwt-framework) discards the Poly1305 authentication tag during key wrapping and omits it during decryption. This degrades the Authenticated Encryption with Associated Data (AEAD) protection to unauthenticated ChaCha20, allowing an attacker to manipulate the encrypted Content Encryption Key (CEK) without detection.

Vulnerability Overview

The experimental implementation of the Chacha20Poly1305 key-encryption algorithm in the PHP web-token/jwt-framework library contains a critical flaw that undermines the integrity of JSON Web Encryption (JWE) tokens. JWE depends on Authenticated Encryption with Associated Data (AEAD) to protect both the confidentiality of the payload and the integrity of the key wrapping structure.

In standard JWE configurations, key encryption algorithms wrap the Content Encryption Key (CEK) using a Key Encryption Key (KEK). When using ChaCha20-Poly1305, the Poly1305 Message Authentication Code (MAC) tag is expected to secure the wrapped key against unauthorized modifications. This vulnerability, tracked under GHSA-6vvh-pxr4-25r7, arises because the implementation fails to persist and verify this cryptographic tag.

The resulting system suffers from missing support for integrity checks (CWE-353) and improper verification of cryptographic signatures (CWE-347). Because the system permits decryption without verification, the cryptographic mechanism degrades from authenticated encryption to an unauthenticated stream cipher, exposing wrapped keys to active tampering during transit.

Cryptographic Root Cause Analysis

The core cryptographic vulnerability lies in how the Chacha20Poly1305 class wraps and unwraps the Content Encryption Key (CEK) using the PHP OpenSSL extension. In a secure ChaCha20-Poly1305 AEAD operation, the cipher generates both ciphertext and a 16-byte authentication tag (Poly1305 MAC) based on the key, nonce, and plaintext. During decryption, this tag must be supplied alongside the ciphertext to verify that no alteration occurred during transit.

Inside the vulnerable encryptKey() function, the library invokes openssl_encrypt() with the chacha20-poly1305 cipher and passes a local variable $tag by reference to capture the generated MAC. Although PHP successfully populates $tag with the 16-byte Poly1305 output, the library fails to store this tag in the JWE header (specifically, $additionalHeader['tag'] is never populated). This step discards the cryptographic guarantee of integrity, sending the JWE token over the wire with only the ciphertext and the nonce.

During decryption, the decryptKey() function extracts the nonce but fails to retrieve or expect a tag. The function calls openssl_decrypt() with only five parameters, omitting the critical sixth parameter which is the expected authentication tag. When PHP's OpenSSL extension is asked to decrypt an AEAD cipher like ChaCha20-Poly1305 without an authentication tag, the extension silently downgrades the operation, treating the cipher as unauthenticated ChaCha20 stream data and bypassing all integrity checks.

Source Code Differential Analysis

To understand the vulnerability, look at the vulnerable implementation of the encryptKey and decryptKey methods in the library. In encryptKey, the $tag reference variable is populated but never exported into the $additionalHeader array. This results in the tag being discarded at the end of the execution scope.

// VULNERABLE
public function encryptKey(JWK $key, string $cek, array $completeHeader, array &$additionalHeader): string
{
    $k = $this->getKey($key);
    $nonce = random_bytes(12);
    $additionalHeader['nonce'] = Base64UrlSafe::encodeUnpadded($nonce);
    $tag = null;
    // The tag is generated by reference but never added to $additionalHeader
    $result = openssl_encrypt($cek, 'chacha20-poly1305', $k, OPENSSL_RAW_DATA, $nonce, $tag);
    if ($result === false || ! is_string($tag)) {
        throw new RuntimeException('Unable to encrypt the CEK');
    }
    return $result;
}

On the decryption side, the decryptKey function similarly omits any verification of the tag. It calls openssl_decrypt using only five arguments, completely ignoring the authentication parameter.

// VULNERABLE
public function decryptKey(JWK $key, string $encrypted_cek, array $header): string
{
    $k = $this->getKey($key);
    $nonce = Base64UrlSafe::decodeNoPadding($header['nonce']);
    if (mb_strlen($nonce, '8bit') !== 12) {
        throw new InvalidArgumentException('The header parameter "nonce" is not valid.');
    }
    // Decryption occurs without providing the $tag parameter
    $result = openssl_decrypt($encrypted_cek, 'chacha20-poly1305', $k, OPENSSL_RAW_DATA, $nonce);
    if ($result === false) {
        throw new RuntimeException('Unable to decrypt the CEK');
    }
    return $result;
}

To correct this vulnerability, the patch implements strict verification on both sides. In the fixed version, the tag is validated to be exactly 16 bytes and is written to $additionalHeader['tag']. On decryption, the presence, type, and length of the tag are enforced, and the tag is explicitly passed as the sixth argument to openssl_decrypt(). This forces OpenSSL to execute the complete AEAD verification phase and fail-closed if the tag has been modified or omitted.

Malleability & Bit-Flipping Exploitation

Because ChaCha20 operates as a stream cipher, it generates a pseudo-random keystream based on the key and nonce, which is then combined with the plaintext using a bitwise XOR operation. Without the integrity guarantees provided by Poly1305, stream ciphers are inherently malleable. An attacker who can manipulate the ciphertext during transit can predict the exact change that will occur in the resulting decrypted plaintext.

An adversary-in-the-middle (AitM) on the network transit path can capture the JWE, isolate the encrypted Content Encryption Key (CEK), and apply bitwise modifications. Specifically, flipping the $i$-th bit of the ciphertext results in an identical bit-flip in the $i$-th bit of the decrypted CEK. Since the server-side decryption routine does not validate a MAC, this altered ciphertext decrypts successfully without throwing an error.

Although the resulting modified CEK will subsequently fail the payload decryption stage (because the payload's own AEAD mechanism, such as AES-GCM, will correctly validate its tag), the server's cryptographic behavior is altered. Attackers can leverage the timing differences, error messages, or side-channel responses resulting from the decrypted-yet-corrupt CEK to conduct advanced cryptographic analysis or construct padding oracle style attacks depending on how downstream components handle key validation failures.

Impact and Cryptographic Assurances Assessment

The impact of this cryptographic degradation is significant for applications relying on the integrity of JWE key-wrapping. By allowing arbitrary modification of the wrapped Content Encryption Key, the library fails to uphold the primary security objectives of JSON Web Encryption. A compromised CEK decryption path means that cryptographic boundaries within the application are compromised.

The vulnerability is assessed with a CVSS v4.0 score of 5.9 (Medium), indicating high impact on integrity (VI:H) but requiring high attack complexity (AC:H) and an adjacent network position (AV:A). High complexity stems from the need to intercept the tokens and construct mathematically precise bit-flipping attacks that map to valid target states or yield readable side-channels.

Because this vulnerability resides in an experimental component (Chacha20Poly1305), its exposure in standard production environments is limited. The vulnerability is not cataloged in the CISA Known Exploited Vulnerabilities (KEV) database, and there are no reports of active exploitation in the wild, classifying it as a theoretical and developmental risk.

Remediation and Defensive Strategies

To fully remediate the vulnerability, developers must upgrade the web-token/jwt-library package to a secure release. The maintainers have provided patches in versions 3.4.10, 4.0.7, and 4.1.7. Run the Composer update command to pull the latest updates.

composer update web-token/jwt-library

If upgrading is not immediately possible due to legacy system constraints, you must disable the experimental Chacha20Poly1305 key-encryption algorithm. Modify your AlgorithmManager initialization code to ensure that the experimental class Jose\Experimental\KeyEncryption\Chacha20Poly1305 is not registered. Replace it with standardized, secure algorithms such as AES Key Wrap (AES-KW) or AES-GCM Key Wrap.

use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Encryption\Algorithm\KeyEncryption\A256GCMKW;
 
// Secure configuration omitting Chacha20Poly1305
$keyEncryptionAlgorithmManager = new AlgorithmManager([
    new A256GCMKW(),
]);

This incident highlights a broader lesson in secure development when interacting with cryptographic wrappers. When implementing AEAD ciphers through native bindings like PHP's OpenSSL extension, developers must ensure that default parameters do not silently downgrade the security of the operation. Always design API boundaries to validate key, tag, and nonce properties before invoking cryptographic operations, ensuring the system fails-closed immediately upon encountering missing or malformed inputs.

Technical Appendix

CVSS Score
5.9/ 10
CVSS:4.0/AV:A/AC:H/AT:N/PR:N/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N

Affected Systems

web-token/jwt-experimentalweb-token/jwt-library

Affected Versions Detail

Product
Affected Versions
Fixed Version
web-token/jwt-library
web-token
>= 3.3.0, < 3.4.103.4.10
web-token/jwt-library
web-token
>= 4.0.0, < 4.0.74.0.7
web-token/jwt-library
web-token
>= 4.1.0, < 4.1.74.1.7
AttributeDetail
Vulnerability TypeCryptographic Integrity Degradation
CWE IDCWE-353, CWE-347
Attack VectorAdjacent Network
CVSS v4.0 Score5.9 (Medium)
Exploit StatusPoC / Regression Tests Available
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1557Adversary-in-the-Middle
Credential Access
T1565.002Data Manipulation: Transmitted Data Manipulation
Impact
CWE-353
Missing Support for Integrity Check

The product does not attempt to verify the integrity of a message or transmission, which can allow attackers to modify the data without detection.

Vulnerability Timeline

GHSA-6vvh-pxr4-25r7 Published
2026-06-18
FriendsOfPHP Advisory Published
2026-06-18
Patched Versions Released (3.4.10, 4.0.7, 4.1.7)
2026-06-18

References & Sources

  • [1]GitHub Security Advisory GHSA-6vvh-pxr4-25r7
  • [2]FriendsOfPHP Security Advisory for web-token/jwt-library
  • [3]web-token/jwt-framework GitHub Repository

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

•36 minutes ago•CVE-2026-0755
9.8

CVE-2026-0755: Remote Code Execution and Arbitrary File Exfiltration in gemini-mcp-tool

CVE-2026-0755 is a critical vulnerability in gemini-mcp-tool (<= 1.1.5) that allows unauthenticated remote code execution on Windows installations and arbitrary local file exfiltration across all supported operating systems. The flaws exist within the execAsync command runner and the input handling logic of the Model Context Protocol (MCP) server, which fails to securely escape arguments passed to Node.js child processes and does not validate local file references in user-supplied prompt strings.

Alon Barad
Alon Barad
1 views•7 min read
•about 1 hour ago•GHSA-G7M4-839X-CH6V
8.7

GHSA-g7m4-839x-ch6v: Denial of Service via Unbounded Digits Parameter in spomky-labs/otphp

The spomky-labs/otphp library prior to version 11.4.3 is vulnerable to an unhandled DivisionByZeroError crash when parsing provisioning URIs containing a digits parameter value equal to or greater than 40. This allows unauthenticated remote attackers to trigger a Denial of Service by supplying a crafted URI, which causes float-to-integer cast overflow and subsequent division-by-zero fatal error in modern PHP runtimes.

Alon Barad
Alon Barad
2 views•7 min read
•about 2 hours ago•GHSA-2JX3-65F3-XR8R
5.3

GHSA-2JX3-65F3-XR8R: Dynamic Property Injection (Mass Assignment) in spomky-labs/otphp

A critical mass-assignment (property injection) vulnerability exists in the PHP One-Time Password (OTP) library spomky-labs/otphp within the Factory::loadFromProvisioningUri method. When an application loads an OTP provisioning URI (such as a QR code configuration link), a hostile URI can inject query parameters that dynamically overwrite internal, private, or read-only object properties of the OTP instance. This behavior leads to application state corruption, validation bypasses, or uncaught TypeErrors that crash the executing application process.

Amit Schendel
Amit Schendel
3 views•7 min read
•about 3 hours ago•GHSA-3PRJ-6HQW-CM82
8.7

GHSA-3PRJ-6HQW-CM82: CPU Amplification Denial of Service in web-token JWT Library

An uncontrolled resource consumption vulnerability in the PBES2-HS* key wrapping algorithms of the web-token JWT library allows remote, unauthenticated attackers to cause a denial of service (DoS) by sending JWE tokens with unbounded iteration counts.

Amit Schendel
Amit Schendel
4 views•5 min read
•about 5 hours ago•GHSA-JC38-X7X8-2XC8
8.1

GHSA-jc38-x7x8-2xc8: Algorithm Confusion and Header Override Vulnerability in PHP JWT Framework

An algorithm confusion vulnerability exists in the PHP JWT Framework (web-token/jwt-library) where the JWSVerifier and JWEDecrypter components merge integrity-protected and unprotected headers using insecure methods. Under specific conditions, duplicate parameters defined in unprotected headers override those in integrity-protected headers, allowing an attacker to bypass cryptographic signature verification.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 6 hours ago•GHSA-5739-39V2-5754
6.3

GHSA-5739-39V2-5754: Bleichenbacher / Marvin Padding Oracle in PHP JWE Decryption (RSAES-PKCS1-v1_5)

An observable timing discrepancy vulnerability in the web-token/jwt-framework library allows unauthenticated remote attackers to perform a Bleichenbacher / Marvin padding oracle attack against JWE tokens using the RSAES-PKCS1-v1_5 algorithm. By failing to perform constant-time implicit rejection on PKCS#1 v1.5 padding failures, the decryption process leaks structural validation errors via exceptions and early returns, exposing the wrapped Content Encryption Key (CEK) to cryptographic recovery.

Amit Schendel
Amit Schendel
5 views•7 min read