CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-84997

CVE-2026-84997: Infinite Loop Denial of Service in ReactPHP HTTP Component

Alon Barad
Alon Barad
Software Engineer

Sep 18, 2026·8 min read·3 visits

Executive Summary (TL;DR)

A logical flaw in ReactPHP's chunked parser allows remote attackers to block the single-threaded event loop indefinitely using malformed chunked transfer encoding payloads, leading to a complete Denial of Service.

An infinite loop vulnerability in ReactPHP's react/http chunked transfer encoding decoder (v0.6.0 up to 1.11.1) allows unauthenticated remote attackers to trigger a denial of service (DoS) by sending crafted chunked requests or responses, completely freezing the single-threaded event loop and pegging CPU usage to 100%.

Vulnerability Overview

ReactPHP relies on an event-driven, non-blocking I/O model implemented on a single-threaded execution model. The react/http component provides streaming HTTP server and client capabilities, allowing concurrent connection management within this single-threaded event loop. Under this architectural paradigm, any blocking operation or infinite loop within a stream decoder immediately halts the entire event loop, stopping execution for all concurrent requests and connections managed by that process.

The vulnerability identified as CVE-2026-84997 is a high-severity denial-of-service vulnerability situated within the stream processing engine of the HTTP message body decoder. Specifically, the flaw resides in the React\Http\Io\ChunkedDecoder class, which handles HTTP messages using Transfer-Encoding: chunked. This decoder is used symmetrically: it processes incoming request bodies for React\Http\HttpServer and incoming response bodies for React\Http\Browser (the ReactPHP HTTP client).

Because the component is deployed on the network perimeter to parse incoming HTTP data streams, it constitutes an exposed attack surface. By presenting specifically structured, malformed HTTP payloads, a remote unauthenticated attacker can exploit logical flaws in the state machine of the chunked decoder. This causes the parser to cycle infinitely without reducing its internal buffer, locking the entire process and generating sustained 100% CPU utilization across the affected core.

Root Cause Analysis

The technical root cause of CVE-2026-84997 lies in the event-driven data parser implemented within React\Http\Io\ChunkedDecoder::handleData($data). The class processes stream data incrementally by appending newly arrived data to an internal string buffer ($this->buffer) and executing a parsing state machine wrapped inside a while ($this->buffer !== '') loop. The parser logic relies on the invariant that every loop iteration must consume a positive number of bytes from the buffer, thereby reducing its length and ensuring the loop eventually terminates when the buffer is empty.

The vulnerability occurs under two distinct input-handling scenarios where this invariant is violated, causing the loop to run with an unchanging buffer state. The first scenario involves an incomplete terminal-chunk trailer. When a chunked stream delivers a terminal chunk (a chunk of size zero, represented by '0\r\n'), the parser searches for the terminating CRLF sequence ('\r\n') using PHP's native strpos function. If the trailer data is truncated or incomplete (such as '0\r\nab'), strpos fails to find the separator and returns the boolean value false.

The class subsequently attempts to slice the buffer up to the position of the CRLF using substr($this->buffer, $positionCrlf). In PHP, when the boolean value false is passed as the second argument to substr, weak type coercion converts it to the integer 0. Consequently, the operation evaluates to substr($this->buffer, 0), which returns the entire, unmodified buffer. Because the buffer size does not shrink, the while loop condition remains satisfied, and the engine enters an infinite loop, blocking the ReactPHP event loop.

The second scenario involves an off-by-one logical error in the parser's post-chunk validation guards. Under RFC 9112, each data chunk must be followed immediately by a CRLF. The decoder maintains an error guard to validate this requirement, which historically executed only if the remaining buffer length was strictly greater than 2 (strlen($this->buffer) > 2). If an attacker delivers a completed chunk followed by exactly two non-CRLF bytes (e.g., '2\r\nabXY'), both the wait guard and the error guard are bypassed. The parser fails to consume the trailing invalid bytes, leaving the buffer unchanged and initiating an infinite loop.

Code Analysis

To comprehend the precise mechanics of the vulnerability and its remediation, we examine the implementation of handleData within src/Io/ChunkedDecoder.php. The vulnerable codebase relied on implicit type coercion and an incorrect length comparison operator to determine whether the stream has reached a valid termination state or contains protocol errors. Below is a comparative representation of the vulnerable parsing logic versus the patched implementation.

// Vulnerable Code Path in src/Io/ChunkedDecoder.php
while ($this->buffer !== '') {
    // ... parsing chunk boundaries ...
    if ($this->chunkSize === 0) {
        // If no CRLF is found, strpos returns false
        $positionCrlf = \strpos($this->buffer, "\r\n");
        
        // BUG: false is coerced to 0, leaving buffer unchanged
        $this->buffer = (string)\substr($this->buffer, $positionCrlf);
    }
 
    // BUG: Strictly greater-than comparison bypasses exactly 2 bytes
    if ($positionCrlf !== 0 && $this->chunkSize !== 0 && $this->chunkSize === $this->transferredSize && \strlen($this->buffer) > 2) {
        $this->handleError(new Exception('Chunk does not end with a CRLF'));
        return;
    }
}

The patch introduced in commit b6d4688790adf3797071fcf88a3fc4225f30486a addresses both flaws directly by introducing strict type validation and corrected mathematical bounds. First, the parser now explicitly checks if $positionCrlf evaluates to false and exits early, waiting for additional stream data. Second, the error guard comparison has been modified from strictly greater than (> 2) to greater than or equal to (>= 2). This forces immediate error handling and stream termination when the buffer contains invalid trailing data of exactly two bytes.

// Patched Code Path in src/Io/ChunkedDecoder.php
while ($this->buffer !== '') {
    // ... parsing chunk boundaries ...
    if ($this->chunkSize === 0) {
        $positionCrlf = \strpos($this->buffer, "\r\n");
        
        // FIX: Explicitly handle incomplete trailer state
        if ($positionCrlf === false) {
            return;
        }
        $this->buffer = (string)\substr($this->buffer, $positionCrlf);
    }
 
    // FIX: Using >= 2 ensures exactly two non-CRLF bytes trigger error handling
    if ($positionCrlf !== 0 && $this->chunkSize !== 0 && $this->chunkSize === $this->transferredSize && \strlen($this->buffer) >= 2) {
        $this->handleError(new Exception('Chunk does not end with a CRLF'));
        return;
    }
}

Exploitation

Exploitation of CVE-2026-84997 does not require privileges or user interaction, and can be executed over standard network channels. The attacker's objective is to transmit a malformed chunked transfer payload that forces the parser into the infinite loop execution path. Because ReactPHP relies on a single event-driven loop thread, a successful exploit instantly blocks all other operations on that thread, resulting in a denial-of-service condition for all concurrent users.

To exploit a server running React\Http\HttpServer, the attacker sends a standard HTTP POST request specifying Transfer-Encoding: chunked. Following the headers, the attacker transmits one of the two trigger payloads. For Scenario A, the payload consists of the terminal chunk marker followed by a non-CRLF character sequence without any closing CRLF (e.g., '0\r\nab'). For Scenario B, the attacker transmits a valid chunk of data, followed by exactly two non-CRLF characters (e.g., '2\r\nabXY').

The exploit can also target client-side applications utilizing React\Http\Browser to communicate with external resources. In this attack vector, a malicious or compromised web server responds to the client's request with a chunked-encoded response body containing the identical payload structures. Upon receipt and parsing of the response by the client's decoder, the client-side event loop freezes, halting all asynchronous tasks running on that process.

Fix Completeness & Risk Assessment

Evaluating the fix completeness of the initial patch reveals that while the logical bugs in the infinite loop paths were resolved, they uncovered a secondary vulnerability. In the initial fix (b6d4688790adf3797071fcf88a3fc4225f30486a), when an incomplete trailer was detected, the parser safely executed a return statement to await additional data. However, if an attacker continuously streamed trailer data without ever sending a terminating CRLF, the buffer would grow unboundedly, leading to system memory exhaustion.

To address this secondary exhaustion vector, the maintainers implemented a follow-up commit (58bc906dcaa5d360830555360bfdeacff3be0260). This patch introduces a hard limit on the allowable trailer size, utilizing a maximum buffer threshold (MAX_CHUNK_HEADER_SIZE of 1024 bytes). If the internal buffer length exceeds this threshold while waiting for the terminating CRLF, the parser throws an exception and closes the connection. This secondary patch is critical to achieving a complete and robust remediation.

With both the infinite loop and the unbounded buffering issues resolved, the current implementation in version 1.11.1 provides complete protection against these attack paths. No obvious bypasses of the state machine constraints remain, as both logical truncation and resource exhaustion vectors have been bounded. Organizations must ensure that the secondary patch is deployed alongside the primary logic changes to prevent alternative Denial of Service vectors.

Remediation & Mitigation Guidance

Remediation of CVE-2026-84997 requires updating the react/http package to version 1.11.1 or higher. This update can be performed using Composer by modifying the project's dependency constraints and executing an update command. Developers must verify that their lock files reflect the installation of the corrected version to ensure that production environments are not running vulnerable code paths.

composer require react/http:^1.11.1

For environments where immediate package updates are impossible, operational mitigations can protect the server-side attack surface. Deploying a robust reverse proxy such as Nginx or HAProxy in front of the ReactPHP application server effectively filters out malformed HTTP requests. These proxies normalize the incoming HTTP stream, reassembling and validating chunked transfer encoding before passing a cleaned request to the ReactPHP backend.

Note that reverse proxy normalization only mitigates the inbound (server) direction of the vulnerability. It provides no defense for outbound clients implemented via React\Http\Browser that connect to malicious third-party endpoints. For outbound client scenarios, the only complete mitigation is upgrading the library to the patched version.

Official Patches

ReactPHPOfficial Security Advisory
ReactPHP GitHubRelease v1.11.1 Changelog

Fix Analysis (4)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Affected Systems

ReactPHP HTTP Server (react/http)ReactPHP HTTP Browser (react/http client)Any server-side PHP framework or server layer that utilizes ReactPHP's stream handlers for Transfer-Encoding processing.

Affected Versions Detail

Product
Affected Versions
Fixed Version
react/http
reactphp
>= 0.6.0, < 1.11.11.11.1
AttributeDetail
CWE IDCWE-835
Attack VectorNetwork (AV:N)
CVSS v3.1 Score7.5 (High)
Exploit StatusPoC available in test suite
KEV StatusNot Listed
ImpactDenial of Service (CPU exhaustion and event-loop freeze)

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-835
Loop with Unreachable Exit Condition ('Infinite Loop')

The program contains an iteration loop with an exit condition that cannot be reached or is bypassed under specific malformed input conditions, causing execution to spin indefinitely.

Known Exploits & Detection

GitHub Security Advisory Integration SuiteReproduction test suites built into the repository to validate scenarios involving incomplete trailers and 2-byte off-by-one errors.

Vulnerability Timeline

Initial fix commit authored by Jacob Sifuentes to resolve the core infinite loop logic
2026-06-25
Follow-up mitigation commit added by Christian Lück to cap incomplete trailer buffer sizes
2026-08-10
Release of v1.11.1 published to Packagist
2026-09-09
CVE-2026-84997 is officially published and assigned
2026-09-16

References & Sources

  • [1]GitHub Security Advisory (GHSA-x424-64qh-5j54)
  • [2]Core Parser Logic Fix Commit
  • [3]Trailer Size Limit Commit
  • [4]Integration Merge Commit
  • [5]Release v1.11.1 Release Notes
  • [6]Release Tag Commit

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•9 minutes ago•CVE-2026-82399
7.5

CVE-2026-82399: Resource Exhaustion Denial of Service in CoreDNS Custom Transports

CVE-2026-82399 is a resource management vulnerability in CoreDNS affecting custom DNS transport pathways. Prior to version 1.14.7, transports including DNS-over-HTTPS (DoH), DNS-over-QUIC (DoQ), and DNS-over-gRPC executed the resource-intensive unpack method of the underlying Go DNS library on raw, untrusted incoming payloads before validating the fixed 12-byte DNS header. An unauthenticated remote attacker can exploit this behavior by using nested DNS name compression pointers to trigger substantial heap allocations, leading to memory exhaustion and server termination.

Amit Schendel
Amit Schendel
1 views•7 min read
•about 2 hours ago•CVE-2026-88976
6.1

CVE-2026-88976: HTML Deserialization Cross-Site Scripting in @platejs/core

Plate core HTML deserialization APIs parse supplied HTML strings in the active document. When an application passes untrusted or cross-user HTML to these APIs, certain HTML attributes can trigger browser behavior before the HTML is converted into editor nodes.

Amit Schendel
Amit Schendel
4 views•6 min read
•about 3 hours ago•CVE-2026-85999
5.3

CVE-2026-85999: Regular Expression Denial of Service (ReDoS) in Soup Sieve css_parser.py

A polynomial-time Regular Expression Denial of Service (ReDoS) vulnerability in Soup Sieve versions prior to 2.9 allows remote unauthenticated attackers to cause CPU exhaustion and thread-pool denial of service. The vulnerability resides in the trailing whitespace and comment preprocessing step of the CSS parser. An attacker can trigger quadratic backtracking by submitting a crafted CSS selector string containing a long run of internal spaces or comments terminated by a non-matching token. This blocks the Python Global Interpreter Lock (GIL) and halts worker threads.

Amit Schendel
Amit Schendel
4 views•6 min read
•about 4 hours ago•CVE-2026-86000
5.3

CVE-2026-86000: Polynomial-Time Regular Expression Denial of Service in Soup Sieve Selector Parser

A regular expression denial of service (ReDoS) vulnerability in Soup Sieve prior to version 2.9 allows remote attackers to cause CPU exhaustion and service disruption. The issue lies within the definition of the IDENTIFIER and VALUE selector sub-patterns in the CSS parser component, which uses overlapping adjacent quantified groups. When parsing long, crafted, or unclosed CSS selectors, backtracking-based regular expression engines experience quadratic performance degradation. User-controlled selectors can reach this path through soupsieve.compile(), soupsieve.select(), or BeautifulSoup.select(), while applications using only hard-coded selectors are unaffected.

Amit Schendel
Amit Schendel
6 views•7 min read
•about 5 hours ago•CVE-2026-86003
7.5

CVE-2026-86003: Unintended Proxying of DNS UPDATE Requests via Alternative Transports in CoreDNS

A protocol-level validation bypass in CoreDNS versions prior to 1.14.7 allows unauthenticated remote attackers to proxy unauthorized DNS UPDATE messages (Opcode 5) using modern alternative transport layers such as DoH, DoH3, DoQ, and gRPC. If upstream authoritative servers trust the CoreDNS server's source IP and do not enforce TSIG authentication, attackers can inject, alter, or delete DNS zone records, leading to potential zone takeover or traffic redirection.

Alon Barad
Alon Barad
5 views•5 min read
•about 6 hours ago•CVE-2026-72695
8.1

CVE-2026-72695: Authenticated Path Traversal and Arbitrary File Deletion in Grav CMS MediaUploadTrait

A path traversal vulnerability exists in Grav CMS versions prior to 2.0.16. The flaw occurs within the file validation mechanisms of the MediaUploadTrait, enabling authenticated users with media management privileges to bypass sandbox limitations. This allows the deletion of arbitrary files on the filesystem, which can result in denial of service or remote code execution.

Amit Schendel
Amit Schendel
4 views•7 min read