Advisories for Composer/Web-Token/Jwt-Experimental package

2026

PHP JWT Framework: JWSVerifier uses algorithm from unprotected header, enabling algorithm confusion attacks

JWSVerifier::getAlgorithm() in src/Library/Signature/JWSVerifier.php (line 144) merges protected and unprotected headers using PHP's spread operator: $completeHeader = […$signature->getProtectedHeader(), …$signature->getHeader()]; In PHP, when spreading arrays with duplicate string keys, the last array's values take precedence. Since the unprotected header (getHeader()) is spread second, an attacker can override the integrity-protected alg parameter by placing a different value in the unprotected header. This creates a Time-of-Check/Time-of-Use (TOCTOU) vulnerability: HeaderCheckerManager validates alg from the protected …

PHP JWT Framework: Chacha20Poly1305 key-encryption algorithm discards the Poly1305 authentication tag, performing no authentication on decryption

The experimental Chacha20Poly1305 key-encryption algorithm generates the 16-byte Poly1305 authentication tag during encryptKey() but discards it: the tag is never written to the header and therefore never reaches the wire. On the receiving side, decryptKey() calls openssl_decrypt('chacha20-poly1305', …) without the tag argument, which makes OpenSSL skip authentication entirely. As a result the AEAD construction is silently degraded to unauthenticated ChaCha20: a tampered encrypted CEK is accepted, and because ChaCha20 is …