Symfony: `HeaderUtils::split()`におけるReDoS脆弱性。`Cache-Control`リクエストヘッダー経由で到達可能。
### 説明
`HeaderUtils::split()`は、トークンの代替パターンでヘッダー値を解析しており、このパターンは空白にも一致していました。また、`(?<!\s)`という前方参照も使用されていました。空白が区切り文字の前に連続して配置されると、囲まれた繰り返し処理の中で指数関数的に多くの方法で分割される可能性があり、エンジンはそれらすべてを試してから結果を決定します。`HeaderBag`は、`Request`オブジェクトが作成されるたびに`Cache-Control`ヘッダーに対してこの関数を呼び出すため、HTTPリクエストを処理するすべてのアプリケーションで脆弱性が存在し、認証は不要です。
このようなヘッダーを含む単一のリクエストは、CPUの約1秒(PHP 8.5で、8KBのヘッダー内に17個の空白がある場合、813ms)を消費します。18個以上の空白があると、`preg_match_all()`は`pcre.backtrack_limit`に達して処理を停止し、`split()`は空の配列を返します。その結果、ヘッダーのすべての指示がサイレントに無視されます。
### 解決策
現在のパターンでは、空白は値の後に続く場合にのみ消費されるようになりました。これにより、値が空白で終わることはできなくなりました。また、何も返却する必要がなくなり、すべての量指定子は「所有」モードになりました。この修正の最初のリリースでは、空白区切り文字での分割が正しく行われなくなりました。具体的には、`HeaderUtils::split('foo bar', ' ')`が、6.4.46から6.4.47、7.4.19から7.4.20、および8.1.7から8.1.8のバージョンで、単一の値しか返さなくなりました。区切り文字として使用される空白文字は、空白の処理部分から除外されるようになりました。この修正は、6.4.48、7.4.21、および8.1.9のバージョンに含まれています。
この問題に対する修正は、[こちら](https://github.com/symfony/symfony/commit/343a1772ce6ac03e48b228d2d7168d19750e3f36)で確認できます(5.4のブランチ用であり、6.4、7.4、8.1、および8.2のブランチにも移植されています)。
### 謝辞
Symfonyは、この問題を報告してくれた[r3verii](https://github.com/r3verii)と、修正を提供してくれたNicolas Grekasに感謝します。
また、Checkmarxの[Bruno Dias](https://github.com/cx-bruno-dias)氏が、CVEの割り当てに協力してくれたことに感謝します。
影響を受けるパッケージ:
- Composer (PHP) symfony/http-foundation: 影響を受けるバージョンは 6.0.1 以降、6.4.46 未満。修正されたバージョンは 6.4.46。
- Composer (PHP) symfony/http-foundation: 影響を受けるバージョンは 7.0.0 以降、7.4.19 未満。修正されたバージョンは 7.4.19。
- Composer (PHP) symfony/http-foundation: 影響を受けるバージョンは 8.0.0 以降、8.1.7 未満。修正されたバージョンは 8.1.7。
- Composer (PHP) symfony/symfony: 影響を受けるバージョンは 6.0.1 以降、6.4.46 未満。修正されたバージョンは 6.4.46。
- Composer (PHP) symfony/symfony: 影響を受けるバージョンは 7.0.0 以降、7.4.19 未満。修正されたバージョンは 7.4.19。
- Composer (PHP) symfony/symfony: 影響を受けるバージョンは 8.0.0 以降、8.1.7 未満。修正されたバージョンは 8.1.7。
- Composer (PHP) symfony/http-foundation: 影響を受けるバージョンは 4.1.0 以降、5.4.54 未満。修正されたバージョンは 5.4.54。
- Composer (PHP) symfony/symfony: 影響を受けるバージョンは 4.1.0 以降、5.4.54 未満。修正されたバージョンは 5.4.54。