Skip to main content
Vulnerability Database/CVE-2026-84997

CVE-2026-84997: React/HTTP Chunked Decoder DoS Vulnerability

CVE-2026-84997 is a denial of service vulnerability in ReactPHP's HTTP implementation that allows attackers to freeze servers or clients through malformed chunked encoding. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-84997 Overview

CVE-2026-84997 is an infinite loop vulnerability [CWE-835] in react/http, an event-driven streaming HTTP client and server implementation for ReactPHP. The flaw resides in React\Http\Io\ChunkedDecoder and affects versions from 0.6.0 through 1.11.0. A malformed Transfer-Encoding: chunked body can cause the decoder to loop indefinitely, consuming CPU resources. The vulnerability impacts both React\Http\HttpServer (request bodies) and React\Http\Browser (response bodies), enabling a malicious client to freeze a server or a hostile server to freeze a client.

Critical Impact

A remote, unauthenticated attacker can trigger a denial-of-service condition by sending a crafted chunked-encoded HTTP body that traps the decoder in an infinite loop.

Affected Products

  • reactphp/http versions 0.6.0 through 1.11.0 (server-side HttpServer)
  • reactphp/http versions 0.6.0 through 1.11.0 (client-side Browser)
  • Any downstream ReactPHP application processing chunked HTTP bodies

Discovery Timeline

  • 2026-09-16 - CVE-2026-84997 published to NVD
  • 2026-09-16 - Last updated in NVD database

Technical Details for CVE-2026-84997

Vulnerability Analysis

The vulnerability is an algorithmic denial-of-service condition in the chunked transfer encoding decoder. The handleData method in ChunkedDecoder processes incoming bytes in a loop that requires the internal buffer to shrink on every iteration. When two specific edge cases occur, the buffer remains unchanged and the loop never terminates, pinning a CPU core at 100% utilization.

Because ReactPHP is single-threaded and event-driven, freezing the decoder blocks the entire event loop. A single malicious connection can render an HttpServer process unresponsive to all other clients. On the client side, a compromised upstream server can freeze any application using React\Http\Browser to fetch responses.

Root Cause

The root cause is missing termination guards in the chunk-parsing state machine. Two conditions trigger the infinite loop. First, when the terminal zero-length chunk is received but the trailer is incomplete, strpos returns false and the buffer is not advanced. Second, when a non-terminal chunk completes with exactly two non-CRLF bytes remaining, both the error branch and the wait branch are bypassed, so the loop iterates again on the same buffer state.

Attack Vector

An attacker exploits the flaw by sending an HTTP request or response with a malformed Transfer-Encoding: chunked body. No authentication is required. A reverse proxy that normalizes inbound requests may shield the server direction, but it does not protect outbound Browser requests to attacker-controlled hosts.

php
                 $this->transferredSize = 0;
                 $this->buffer = (string)\substr($this->buffer, 2);
             } elseif ($this->chunkSize === 0) {
+                if ($positionCrlf === false) {
+                    // end chunk received, but trailer is incomplete
+                    return;
+                }
                 // end chunk received, skip all trailer data
                 $this->buffer = (string)\substr($this->buffer, $positionCrlf);
             }
 
-            if ($positionCrlf !== 0 && $this->chunkSize !== 0 && $this->chunkSize === $this->transferredSize && \strlen($this->buffer) > 2) {
-                // the first 2 characters are not CRLF, send error event
+            if ($positionCrlf !== 0 && $this->chunkSize !== 0 && $this->chunkSize === $this->transferredSize && \strlen($this->buffer) >= 2) {
+                // chunk is completely transferred, but the following two bytes are not a CRLF, send error event
                 $this->handleError(new Exception('Chunk does not end with a CRLF'));
                 return;
             }

Source: GitHub Commit b6d4688. The patch adds an early return when the trailer is incomplete and changes the boundary check from > 2 to >= 2 so that exactly two non-CRLF trailing bytes now raise an error instead of looping.

Detection Methods for CVE-2026-84997

Indicators of Compromise

  • A ReactPHP worker process consuming 100% CPU on a single core while accepting no new work.
  • HTTP connections that remain open indefinitely without the server sending a response or emitting log entries.
  • Client applications using React\Http\Browser that hang after receiving partial response headers from an untrusted host.

Detection Strategies

  • Inventory PHP dependencies for reactphp/http versions below 1.11.1 using composer.lock scans across repositories and build artifacts.
  • Monitor process-level CPU metrics for ReactPHP workers and alert on sustained single-core saturation with no corresponding request throughput.
  • Inspect HTTP traffic for malformed Transfer-Encoding: chunked bodies where the terminator sequence is missing or truncated.

Monitoring Recommendations

  • Enable request-duration and event-loop-lag metrics in ReactPHP applications and alert when the event loop stalls beyond a defined threshold.
  • Capture and retain access logs from any reverse proxy fronting ReactPHP services to correlate stuck connections to source IPs.
  • Track outbound Browser request timings and set aggressive read timeouts on connections to third-party hosts.

How to Mitigate CVE-2026-84997

Immediate Actions Required

  • Upgrade reactphp/http to version 1.11.1 or later across all affected services and client applications.
  • Audit outbound HTTP integrations using React\Http\Browser and restrict connections to trusted endpoints until patched.
  • Deploy a reverse proxy that validates and normalizes chunked-encoded request bodies in front of any exposed HttpServer instance.

Patch Information

The fix is available in reactphp/http version 1.11.1. Details are published in the GitHub Security Advisory GHSA-x424-64qh-5j54 and the v1.11.1 release notes. Update via Composer and redeploy affected workers.

Workarounds

  • Place a hardened reverse proxy such as nginx or HAProxy in front of the server to reject malformed chunked bodies before they reach ReactPHP.
  • Enforce short idle and read timeouts on both server and client connections to bound the impact of a stuck decoder.
  • Limit outbound Browser requests to allowlisted hosts to reduce exposure to malicious upstream responses.
bash
# Configuration example
composer require reactphp/http:^1.11.1
composer update reactphp/http
php -r "echo \Composer\InstalledVersions::getVersion('reactphp/http');"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.