
Cloud Vulnerability DB
A community-led vulnerabilities database
JSONGeneralSerializer::unserialize(), which parses a JWS in the JSON General serialization, added the signatures of the token one at a time with JWS::addSignature(). That method returns a modified clone of the token, so each call copied the list of the signatures already added, and parsing took a time proportional to the square of their number. The sender of the token chooses that number, and the shortest entry the serializer accepts, {"signature":""}, is 17 bytes long with its comma.
Parsing happens before any header checker, algorithm or key is consulted: no key and no valid token are needed. A 510 KB token holding 30,000 empty signatures kept a PHP worker busy for about 4 seconds, and a 1 MB token for about 18 seconds, while a genuine token of the same size is parsed in 5 to 10 milliseconds. The cost is multiplied by four each time the size doubles, until max_execution_time stops the request, so a handful of concurrent requests can occupy every worker of a pool.
Nothing is disclosed and no token is accepted: the impact is a denial of service.
Applications that parse JWS from untrusted senders with the JSON General serializer (JSONGeneralSerializer, name jws_json_general), through:
JWSLoader or a JWSSerializerManager that has this serializer;JWSEncoder). It builds its manager from every registered serializer and ignores the requested format, so decoding jws_compact through the Symfony Serializer also parses JSON General tokens.
The token has to be sent in a request body of several hundred kilobytes: a token that fits in an HTTP header (8 KB, about 470 signatures) is parsed in about one millisecond. Applications that only use the compact or JSON Flattened serializers directly are not affected, and neither are the JWE serializers.
The code is as old as the library.The serializer now builds the list of signatures and gives it to the JWS constructor at once, so parsing time grows linearly with the size of the token: 30,000 signatures are parsed in about 45 ms and 60,000 in about 145 ms. The input is checked in the same order as before. This fix does not limit the number of signatures.
Fixed in 3.4.13, 4.0.9, 4.1.11 and 4.2.6. 3.4.13 is the last release of the 3.4 branch, which has reached its end of life: users of 3.4 should move to 4.x.
Compatibility. The tokens that are parsed, and the tokens that are rejected, are unchanged. Two edge cases change:
JWS constructor reads the signatures from an optional fourth argument, a list of Signature objects, that is not declared in its signature yet. A fourth argument used to be ignored; a value that is not a list of Signature objects now throws an InvalidArgumentException;header member is not a JSON object, the message of the TypeError names Signature::__construct() instead of JWS::addSignature().Until you upgrade, for the code paths that handle tokens from untrusted senders:
JWSSerializerManager or the JWSLoader without the jws_json_general serializer. With the bundle, decode untrusted tokens with such a manager instead of the Symfony Serializer JWSEncoder;Reported by Anthropic's OSS Scanner (ANT-2026-V2YEUZWG).
Source: NVD
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."