GHSA-jc38-x7x8-2xc8
## Summary `JWSVerifier::getAlgorithm()` in `src/Library/Signature/JWSVerifier.php` (line 144) merges protected and unprotected headers using PHP's spread operator: ```php $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: 1. `HeaderCheckerManager` validates `alg` from the **protected** header 2. `JWSVerifier` uses `alg` from the **unprotected** header for actual verification The same issue exists in `JWEDecrypter.php` (lines 120-124) where `array_merge()` exhibits the same last-wins behavior for `alg` and `enc`. ## Affected Code **JWSVerifier.php line 144** — Spread operator merge order allows unprotected header to override `alg`: ```php $completeHeader = [...$signature->getProtectedHeader(), ...$signature->getHeader()]; ``` **JWEDecrypter.php lines 120-124** — `array_merge()` with same last-wins behavior: ```php $completeHeader = array_merge( $jwe->getSharedProtectedHeader(), $jwe->getSharedHeader(), $recipient->getHeader() ); ``` ## Attack Vectors ### Vector A — Mixed key sets (HIGH probability) If the application uses a JWKSet containing keys of different types (common in multi-tenant or federation scenarios), the JWSVerifier iterates all keys (line 86). An attacker can force a different algorithm that matches a different key in the set. ### Vector B — alg ONLY in unprotected header (HIGH probability) If `alg` is placed EXCLUSIVELY in the unprotected header (not in the protected header at all), `HeaderCheckerManager::checkDuplicatedHeaderParameters()` does NOT trigger. The JSON Flattened/General serializers allow tokens with no protected header or a protect
Properties
- ghsa_id
- GHSA-jc38-x7x8-2xc8
- severity
- high
- summary
- PHP JWT Framework: JWSVerifier uses algorithm from unprotected header, enabling algorithm confusion attacks
- cve_id
- GHSA-jc38-x7x8-2xc8
- is_ghsa_only
- true
- ghsa_published
- 2026-06-18T21:09:17Z
- source_url
- https://github.com/advisories/GHSA-jc38-x7x8-2xc8
- ghsa_updated
- 2026-06-18T21:09:20Z
Related Entities (6)
VULNERABLE_TO (2)
AFFECTS (2)
HAS_WEAKNESS (1)
REPORTED_BY (1)
Explore deeper with Ninja Signal's threat intelligence graph