Skip to content
Heist/ feed
Back to feed
HighFix available

react/http: Unbounded HTTP Client Response Header Buffering Leads to Memory Exhaustion DoS

Type: advisorySources: OSV

### Summary `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. This 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. ### Details `ClientRequestStream::handleData()` is bound directly to the underlying connection's `data` event, so every byte the peer sends is appended with no size check: ```php public function handleData($data) { $this->buffer .= $data; // buffer until double CRLF (or double LF for compatibility with legacy servers) $eom = \strpos($this->buffer, "\r\n\r\n"); $eomLegacy = \strpos($this->buffer, "\n\n"); if ($eom !== false || $eomLegacy !== false) { ``` The 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. The codebase already applies this class of limit elsewhere, but not symmetrically. `RequestHeaderParser` caps incoming **request** headers when ac

Products
react/http
Affected versions
v1.0.0, v1.1.0, v1.10.0, v1.11.0, v1.2.0, v1.3.0, v1.4.0, v1.5.0, v1.6.0, v1.7.0, v1.8.0, v1.9.0
Fixed versions
1.11.1
CVEs
CVE-2026-104827
Confirmed fixed CVEs
Not specified
Updated in this feed
30 Oct 2026, 19:14 UTC · Revision 1

Source evidence

react/http: Unbounded HTTP Client Response Header Buffering Leads to Memory Exhaustion DoS

core-osv · Original source

Published 15 Oct 2026, 20:09 UTC

### Summary `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. This 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. ### Details `ClientRequestStream::handleData()` is bound directly to the underlying connection's `data` event, so every byte the peer sends is appended with no size check: ```php public function handleData($data) { $this->buffer .= $data; // buffer until double CRLF (or double LF for compatibility with legacy servers) $eom = \strpos($this->buffer, "\r\n\r\n"); $eomLegacy = \strpos($this->buffer, "\n\n"); if ($eom !== false || $eomLegacy !== false) { ``` The 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. The codebase already applies this class of limit elsewhere, but not symmetrically. `RequestHeaderParser` caps incoming **request** headers when ac

osv:GHSA-g4f2-2pf3-2pwj

react/http

Fixed versions: 1.11.1

Complete source record
{
  "id": "0cd478e5727c1de70ed60a88dabcd40e8e26cbe94131c307fc51bc93816bafc0",
  "url": "https://osv.dev/vulnerability/GHSA-g4f2-2pf3-2pwj",
  "method": "structured",
  "payload": {
    "kind": "advisory",
    "title": "react/http: Unbounded HTTP Client Response Header Buffering Leads to Memory Exhaustion DoS",
    "summary": "### Summary `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. This 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. ### Details `ClientRequestStream::handleData()` is bound directly to the underlying connection's `data` event, so every byte the peer sends is appended with no size check: ```php public function handleData($data) { $this->buffer .= $data; // buffer until double CRLF (or double LF for compatibility with legacy servers) $eom = \\strpos($this->buffer, \"\\r\\n\\r\\n\"); $eomLegacy = \\strpos($this->buffer, \"\\n\\n\"); if ($eom !== false || $eomLegacy !== false) { ``` The 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. The codebase already applies this class of limit elsewhere, but not symmetrically. `RequestHeaderParser` caps incoming **request** headers when ac",
    "evidence": "osv:GHSA-g4f2-2pf3-2pwj",
    "products": [
      {
        "name": {
          "value": "react/http",
          "evidence": "/affected/0/package/name"
        },
        "prerequisites": [],
        "fixed_versions": [
          {
            "value": "1.11.1",
            "evidence": "/affected/0/ranges"
          }
        ],
        "affected_versions": [
          {
            "value": "v1.0.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.1.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.10.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.11.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.2.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.3.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.4.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.5.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.6.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.7.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.8.0",
            "evidence": "/affected/0/versions"
          },
          {
            "value": "v1.9.0",
            "evidence": "/affected/0/versions"
          }
        ]
      }
    ],
    "severity": "high",
    "structured": {
      "id": "GHSA-g4f2-2pf3-2pwj",
      "aliases": [
        "CVE-2026-104827",
        "GHSA-g4f2-2pf3-2pwj"
      ],
      "metrics": [
        {
          "type": "CVSS_V3",
          "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
        }
      ],
      "affected": [
        {
          "ranges": [
            {
              "type": "ECOSYSTEM",
              "events": [
                {
                  "introduced": "1.0.0"
                },
                {
                  "fixed": "1.11.1"
                }
              ]
            }
          ],
          "package": {
            "name": "react/http",
            "purl": "pkg:composer/react/http",
            "ecosystem": "Packagist"
          },
          "versions": [
            "v1.0.0",
            "v1.1.0",
            "v1.10.0",
            "v1.11.0",
            "v1.2.0",
            "v1.3.0",
            "v1.4.0",
            "v1.5.0",
            "v1.6.0",
            "v1.7.0",
            "v1.8.0",
            "v1.9.0"
          ],
          "database_specific": {
            "source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-g4f2-2pf3-2pwj/GHSA-g4f2-2pf3-2pwj.json",
            "last_known_affected_version_range": "<= 1.11.0"
          }
        }
      ],
      "modified": "2026-10-15T20:30:06.075181740Z",
      "provider": "osv",
      "references": [
        "https://github.com/reactphp/http/security/advisories/GHSA-g4f2-2pf3-2pwj",
        "https://github.com/reactphp/http/commit/2558622d0b76227c60c61eac8a61572cb6638e8c",
        "https://github.com/reactphp/http",
        "https://github.com/reactphp/http/releases/tag/v1.11.1"
      ],
      "provider_metadata": {
        "cwe_ids": [
          "CWE-770"
        ],
        "severity": "HIGH",
        "github_reviewed": true,
        "nvd_published_at": null,
        "github_reviewed_at": "2026-10-15T20:09:56Z"
      }
    },
    "related_cves": [
      {
        "value": "CVE-2026-104827",
        "evidence": "/aliases"
      }
    ],
    "security_relevant": true,
    "severity_evidence": "/database_specific/severity"
  },
  "source_id": "core-osv",
  "document_id": 336049,
  "published_at": "2026-10-15T20:09:56+00:00"
}