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·16 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

•38 minutes ago•CVE-2026-63127
8.2

CVE-2026-63127: OAuth Resource Spoofing and Token Leakage in rmcp SDK

An OAuth resource spoofing vulnerability in the rmcp crate prior to 2.0.0 allows a malicious Model Context Protocol (MCP) server to spoof protected resource metadata. By presenting metadata pointing to a legitimate resource and authorization server, the attacker can trick the client into completing the authentication flow and subsequently sending the authorized token back to the malicious server.

Alon Barad
Alon Barad
1 views•7 min read
•about 2 hours ago•CVE-2026-63128
7.5

CVE-2026-63128: Uncontrolled Resource Consumption in Model Context Protocol Rust SDK (rmcp)

CVE-2026-63128 is a high-severity uncontrolled resource consumption vulnerability in the Model Context Protocol (MCP) official Rust SDK (the rmcp crate) prior to version 2.0.0. An unauthenticated attacker can exploit this vulnerability by sending malformed or mismatching handshake requests to the stateful Streamable HTTP server, causing persistent memory allocation without cleanup. This results in an unbounded memory leak and lock contention that ultimately leads to complete denial of service.

Amit Schendel
Amit Schendel
2 views•6 min read
•about 3 hours ago•CVE-2026-63671
8.1

CVE-2026-63671: Cross-Site Scripting (XSS) Sanitizer Bypass in @nuxtjs/mdc

A cross-site scripting (XSS) vulnerability was identified in @nuxtjs/mdc prior to version 0.22.1. Gaps in the HTML/SVG attribute verification and URL protocol parsing allow unauthenticated remote attackers to bypass the application's sanitization routines. By embedding malicious SVG links or data-encoded iframe elements within Markdown, attackers can execute arbitrary JavaScript in the victim's browser context.

Amit Schendel
Amit Schendel
3 views•6 min read
•about 4 hours ago•CVE-2026-58657
6.5

CVE-2026-58657: Stored CSS Injection in Grav CMS Media Resize Parser

CVE-2026-58657 is a critical stored CSS injection vulnerability in Grav CMS's media processing pipeline. By exploiting improper sanitization of image dimensions in the resize helper, low-privileged users with page editing permissions can inject arbitrary CSS styles. This can lead to visual defacement, UI redressing, and indirect data exfiltration.

Alon Barad
Alon Barad
2 views•4 min read
•about 5 hours ago•CVE-2026-61709
5.3

CVE-2026-61709: Improper Policy Enforcement and Exclusion Bypass in OpenFGA ListUsers API

An authorization-decision over-inclusion vulnerability exists in the OpenFGA authorization engine. The flaw manifests within the `ListUsers` API evaluation path when evaluating complex relationship intersections containing exclusions. Under certain configurations involving wildcards, the exclusion is bypassed, leading to incorrect permission lists.

Alon Barad
Alon Barad
8 views•7 min read
•about 6 hours ago•CVE-2026-61594
9.1

CVE-2026-61594: Authorization Bypass on WebSocket and SSE Mount Paths in djust

An authorization bypass vulnerability exists in the djust framework (djust-org/djust) prior to version 1.0.7. The framework fails to enforce standard Django view-level authorization mechanisms, such as AccessMixins or dispatch decorators, when mounting reactive views over stateful transport layers (WebSockets and Server-Sent Events). Unauthenticated or low-privileged attackers can establish persistent connections to mount arbitrary protected views and execute state-changing event handlers.

Amit Schendel
Amit Schendel
8 views•7 min read