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-118750

CVE-2026-118750: Uncontrolled Resource Allocation in ASP.NET Core FileBufferingReadStream

Amit Schendel
Amit Schendel
Senior Security Researcher

Nov 11, 2026·10 min read·3 visits

Executive Summary (TL;DR)

An unauthenticated remote attacker can trigger an application-level Denial of Service in ASP.NET Core web applications using Microsoft.AspNetCore.WebUtilities (< 2.3.14) by initiating concurrent buffered HTTP requests that prematurely exhaust the shared ArrayPool<byte> via eager constructor allocations in FileBufferingReadStream.

CVE-2026-118750 is an uncontrolled resource allocation vulnerability (CWE-770) affecting the Microsoft.AspNetCore.WebUtilities component in ASP.NET Core. Specifically, the FileBufferingReadStream class eagerly allocates large memory buffers from the shared ArrayPool<byte> inside its constructor prior to reading any incoming request payload data. An unauthenticated remote attacker can exploit this behavior by opening numerous concurrent connections and stalling or omitting request body transmission, exhausting shared memory pools and causing a server-wide Denial of Service (DoS).

Vulnerability Overview

The Microsoft.AspNetCore.WebUtilities package provides core utilities for ASP.NET Core applications, including helpers for parsing multipart form data, handling query strings, and buffering incoming HTTP request streams. A critical component within this package is FileBufferingReadStream, a stream wrapper designed to enable seekable reads over non-seekable network streams. It achieves this by caching incoming data in memory up to a specified threshold (memoryThreshold) before spilling excess payload data to a temporary file on disk.

In versions of Microsoft.AspNetCore.WebUtilities prior to 2.3.14, FileBufferingReadStream exhibits a flaw classified under CWE-770 (Allocation of Resources Without Limits or Throttling). When an endpoint processes a buffered request or multipart form submission, the framework instantiates FileBufferingReadStream. During instantiation, the constructor immediately rents a byte array equal in size to the full memoryThreshold (commonly 30 KB or higher) from the application's shared ArrayPool<byte>.

Because this allocation occurs eagerly inside the constructor rather than lazily during stream read operations, the memory reservation happens before the server verifies whether the client has transmitted any payload bytes. An unauthenticated remote attacker can exploit this design over the network (AV:N) by initiating a high volume of concurrent HTTP requests targeting endpoints that utilize request buffering.

By holding these connections open while transmitting zero bytes or trickling data at an artificially slow rate, the attacker forces the server to lock up large segments of the ArrayPool<byte>. Once the shared pool is depleted, subsequent allocations fall back to standard heap allocations, inducing severe Garbage Collection (GC) thrashing, memory starvation, and a complete Denial of Service (DoS) for legitimate application users.

Root Cause Analysis

The root cause of CVE-2026-118750 lies in the memory management lifecycle of FileBufferingReadStream. In high-performance .NET web servers, ArrayPool<byte> is used to rent and return large byte arrays to avoid frequent allocations on the Large Object Heap (LOH) and reduce garbage collection overhead. However, the efficacy of object pooling depends on minimizing both the size of the rented buffer and the duration for which it is held.

Prior to commit 9a26c7414a4fbff45535c0830253c1b4479b0073, both constructor overloads of FileBufferingReadStream contained logic that checked whether the configured memoryThreshold was less than _maxRentedBufferSize (typically 1 MB). When this condition evaluated to true, the constructor immediately executed _bytePool.Rent(memoryThreshold) and wrapped the resulting array in a standard System.IO.MemoryStream.

This implementation introduces two distinct resource management defects. First, it performs eager pre-allocation: the buffer is reserved at object creation time rather than when data actually arrives on the wire. If an HTTP request contains a Content-Length of zero, or if the client delays sending the request body after transmitting the HTTP headers, the rented buffer sits idle in memory.

Second, the constructor forces fixed maximum sizing for all in-memory buffers. Even if a client sends a tiny 16-byte form field, the stream rents a buffer sized to memoryThreshold (defaulting to 30,720 bytes in standard multipart readers). Because ArrayPool<byte>.Rent rounds requests up to the nearest power of two, a 30 KB request actually rents a 32,768-byte array. Under concurrent connection floods, this 2000x amplification factor between actual payload data and reserved memory rapidly exhausts the memory pool buckets.

Code Analysis

The vulnerability was remediated in commit 9a26c7414a4fbff45535c0830253c1b4479b0073 by removing the direct _rentedBuffer management from FileBufferingReadStream and delegating in-memory buffering to a newly introduced internal stream implementation: PooledMemoryStream.

In the vulnerable implementation, the constructor directly rented the buffer and initialized a MemoryStream over the raw array:

// VULNERABLE CODE: src/Http/WebUtilities/src/FileBufferingReadStream.cs
private Stream _buffer;
private byte[] _rentedBuffer;
 
public FileBufferingReadStream(
    Stream inner,
    int memoryThreshold,
    long? bufferLimit,
    Func<string> tempFileDirectoryAccessor,
    ArrayPool<byte> bytePool)
{
    // ... validation omitted ...
    _bytePool = bytePool;
    if (memoryThreshold < _maxRentedBufferSize)
    {
        // Defect: Immediately rents the full threshold size before any I/O occurs
        _rentedBuffer = bytePool.Rent(memoryThreshold);
        _buffer = new MemoryStream(_rentedBuffer);
        _buffer.SetLength(0);
    }
    else
    {
        _buffer = new MemoryStream();
    }
}

The patch replaces the eager bytePool.Rent call and the _rentedBuffer field with an instance of PooledMemoryStream:

// PATCHED CODE: src/Http/WebUtilities/src/FileBufferingReadStream.cs
private Stream _buffer;
// _rentedBuffer field removed
 
public FileBufferingReadStream(
    Stream inner,
    int memoryThreshold,
    long? bufferLimit,
    Func<string> tempFileDirectoryAccessor,
    ArrayPool<byte> bytePool)
{
    // ... validation omitted ...
    _bytePool = bytePool;
    if (memoryThreshold < _maxRentedBufferSize)
    {
        // Fix: Instantiates PooledMemoryStream without renting from bytePool yet
        _buffer = new PooledMemoryStream(bytePool, memoryThreshold);
    }
    else
    {
        _buffer = new MemoryStream();
    }
}

PooledMemoryStream alters the allocation behavior by keeping its internal _buffer reference as null upon construction. When Write or WriteAsync is invoked as actual bytes are read from the underlying network stream, PooledMemoryStream.EnsureCapacity calculates the required capacity and rents a minimally sized buffer (starting at _initialCapacity of 256 bytes or the incoming write size). As additional data arrives, it grows the buffer geometrically (doubling capacity up to _maxCapacity, which is set to memoryThreshold) and returns the smaller buffer to the ArrayPool<byte>.

Furthermore, the patch updates the disk spill-over logic inside Read and ReadAsync. When the stream length exceeds memoryThreshold and transitions to a temporary FileStream, the patched code uses a using (oldBuffer) block. If oldBuffer is a PooledMemoryStream, it copies the data directly from pooledBuffer.Buffer to the file stream and disposes of oldBuffer, which automatically returns the rented array to _bytePool. For the else branch (used when memoryThreshold >= _maxRentedBufferSize), the patch also wraps the temporary copy buffer in a try/finally block to guarantee _bytePool.Return(rentedBuffer) is executed even if an I/O exception occurs during file writing.

> [!NOTE] > Fix Completeness Assessment: The introduction of PooledMemoryStream completely resolves the pre-allocation issue for zero-byte and small payloads. Additionally, adding the try/finally block around the fallback MemoryStream copy routine fixes a secondary potential pool leak during disk I/O failures.

Exploitation

Exploiting CVE-2026-118750 does not require authentication, special privileges, or complex payload crafting. The attack surface includes any public-facing ASP.NET Core endpoint that invokes FileBufferingReadStream directly or indirectly—most commonly endpoints accepting IFormFile, processing MultipartReader, or using middleware that invokes HttpRequestRewindExtensions.EnableBuffering().

An attacker executes the exploitation methodology through the following steps:

  1. Target Identification: The attacker locates an HTTP endpoint on the target ASP.NET Core application that processes multipart form submissions or enables request body buffering.
  2. Connection Establishment: The attacker initiates thousands of concurrent TCP connections (or multiplexed HTTP/2 streams) to the target web server.
  3. Header Transmission: Over each connection or stream, the attacker sends valid HTTP POST headers specifying a Content-Type: multipart/form-data; boundary=... and a valid Content-Length header, prompting the ASP.NET Core routing and model binding pipeline (or custom middleware) to initialize FileBufferingReadStream.
  4. Resource Locking (Slowloris Pattern): Immediately upon entering the stream constructor, the server rents a 32 KB (or larger, depending on configuration) byte array per request. The attacker thenwithholds the HTTP request body or transmits single bytes at intervals just frequent enough to bypass the server's minimum data rate timeout.
  5. Pool Exhaustion: Because ArrayPool<byte>.Shared maintains a bounded number of arrays per size bucket, holding thousands of 32 KB buffers simultaneously empties the bucket. Subsequent requests (including legitimate traffic across unrelated parts of the application that rely on ArrayPool<byte>.Shared) force the runtime to allocate brand-new byte arrays on the managed heap.

As the attacker cycles or maintains these stalled connections, the application experiences rapid heap growth and continuous Generation 2 garbage collection pauses, degrading throughput until the process becomes unresponsive or terminates with an OutOfMemoryException.

Impact Assessment

The primary impact of CVE-2026-118750 is a high-severity loss of service availability, reflected in its CVSS v3.1 score of 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H). Because the vulnerability affects ArrayPool<byte>.Shared—which is a process-wide singleton in .NET—exhausting the pool in one vulnerable endpoint degrades performance across the entire ASP.NET Core worker process, including Kestrel's internal I/O pipelines and serialization routines.

MetricValueTechnical Justification
Attack Vector (AV)Network (N)Exploitable remotely via standard HTTP/1.1 or HTTP/2 requests.
Attack Complexity (AC)Low (L)Requires no specialized conditions; default buffering thresholds are vulnerable.
Privileges Required (PR)None (N)Can be triggered on any unauthenticated endpoint using request buffering or form uploads.
User Interaction (UI)None (N)Exploitation is completely autonomous.
Confidentiality / IntegrityNone (N)Does not permit reading uninitialized memory or modifying server state.
Availability Impact (A)High (H)Causes process-wide memory starvation, GC thrashing, and service unavailability.

Even when PooledMemoryStream is not present in older builds, the vulnerability does not expose uninitialized memory from the ArrayPool<byte> to the caller because FileBufferingReadStream previously called _buffer.SetLength(0) after wrapping _rentedBuffer in a MemoryStream. Consequently, there is no Confidentiality (C:N) or Integrity (I:N) impact.

As of publication, CVE-2026-118750 is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog, and its Exploit Code Maturity is classified as Unproven (E:U). However, because the mechanics required to trigger the flaw are identical to standard Slowloris or concurrent POST flood attacks, existing load-testing tools and HTTP stress scripts can trigger the condition without modification.

Remediation

To remediate CVE-2026-118750, development and operations teams must upgrade the Microsoft.AspNetCore.WebUtilities NuGet package to version 2.3.14 or later. This version incorporates PooledMemoryStream, ensuring that memory buffers are rented lazily and sized proportionally to the actual incoming payload.

Update the package reference in your project file (.csproj):

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.3.14" />
</ItemGroup>

If immediate package upgrading is not feasible, administrators can apply defense-in-depth mitigations at both the Kestrel web server layer and the perimeter reverse proxy layer to restrict the number and duration of concurrent stalled requests.

First, configure Kestrel's request limits to enforce strict concurrent connection bounds and minimum request body data rates. This ensures that clients holding connections open without transmitting payload data are disconnected rapidly, freeing the FileBufferingReadStream and returning its rented buffer to the ArrayPool<byte>:

builder.WebHost.ConfigureKestrel(serverOptions =>
{
    // Cap maximum concurrent connections to prevent unbounded pool exhaustion
    serverOptions.Limits.MaxConcurrentConnections = 1000;
 
    // Terminate requests that fail to transmit body data at an acceptable rate
    serverOptions.Limits.MinRequestBodyDataRate = new MinDataRate(
        bytesPerSecond: 240,
        gracePeriod: TimeSpan.FromSeconds(5));
});

Second, configure upstream reverse proxies (such as NGINX, HAProxy, Envoy, or cloud load balancers) to buffer incoming request bodies before forwarding them to the backend ASP.NET Core Kestrel server, and enforce strict per-IP rate limiting and client body timeouts (e.g., client_body_timeout 10s; in NGINX). When a reverse proxy buffers the entire request before forwarding it to Kestrel, FileBufferingReadStream receives the payload immediately at local network speeds, minimizing the time window during which buffers remain rented from the pool.

Official Patches

MicrosoftMicrosoft Security Response Center (MSRC) Advisory for CVE-2026-118750
GitHub (dotnet/aspnetcore)Official patch commit introducing PooledMemoryStream in FileBufferingReadStream

Fix Analysis (1)

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

Microsoft.AspNetCore.WebUtilitiesASP.NET Core

Affected Versions Detail

Product
Affected Versions
Fixed Version
Microsoft.AspNetCore.WebUtilities
Microsoft
>= 2.3.12, < 2.3.142.3.14
AttributeDetail
CVE IDCVE-2026-118750
Weakness ClassCWE-770 (Allocation of Resources Without Limits or Throttling)
CVSS v3.1 Score7.5 High (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Affected ComponentMicrosoft.AspNetCore.WebUtilities (FileBufferingReadStream)
Vulnerable Versions>= 2.3.12, < 2.3.14
Patched Version2.3.14
Primary ImpactEndpoint Denial of Service (Memory Pool Exhaustion)
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-770
Allocation of Resources Without Limits or Throttling

The software allocates a finite resource without providing sufficient limits or throttling on how much of that resource can be consumed simultaneously.

Vulnerability Timeline

Fix commit 9a26c7414a4fbff45535c0830253c1b4479b0073 merged into dotnet/aspnetcore repository.
2026-10-27
CVE-2026-118750 officially published by Microsoft CNA on CVE.org and indexed by NVD.
2026-11-10
CVE record metadata updated on CVE.org.
2026-11-11

References & Sources

  • [1]Microsoft Security Update Guide: CVE-2026-118750
  • [2]CVE.org Official Record: CVE-2026-118750
  • [3]GitHub Commit 9a26c7414a4fbff45535c0830253c1b4479b0073: Make FileBufferingReadStream lazily rent buffer
  • [4]MITRE ATT&CK Tactic: Impact (TA0040)
  • [5]MITRE ATT&CK Search for CVE-2026-118750
  • [6]Shodan CVEDB Entry: CVE-2026-118750

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-120006
7.5

CVE-2026-120006: Elevation of Privilege in .NET Aspire via Unintended Dashboard Endpoint Tunneling

An elevation of privilege vulnerability exists in .NET Aspire versions prior to 13.6.5 due to the insertion of sensitive information into sent data (CWE-201). When the Developer Control Plane (DCP) container tunneling feature is enabled, the orchestration engine implicitly exposes all endpoints of the Aspire Dashboard—including its administrative frontend and management APIs—to containerized workloads instead of restricting tunnel access solely to OpenTelemetry Protocol (OTLP) collection endpoints. This exposure allows an attacker operating within a compromised or untrusted container to query the dashboard frontend, extract sensitive environment variables and connection strings, and elevate privileges across the host orchestration boundary.

Amit Schendel
Amit Schendel
0 views•10 min read
•about 2 hours ago•CVE-2026-114155
7.5

CVE-2026-114155: Local Elevation of Privilege via TOCTOU Race Condition in Microsoft .NET dotnet-watch

CVE-2026-114155 is a local elevation of privilege vulnerability affecting Microsoft .NET on Linux and macOS platforms. The vulnerability exists within the dotnet-watch (Hot Reload) component and is caused by a Time-of-Check Time-of-Use (TOCTOU) race condition (CWE-367) during the generation and execution of temporary XML solution files (.slnx) in shared system temporary directories. A local attacker with low privileges can intercept and modify the temporary solution file before MSBuild evaluates it, achieving arbitrary code execution in the security context of the user running dotnet-watch.

Alon Barad
Alon Barad
2 views•9 min read
•about 3 hours ago•CVE-2026-118748
7.5

CVE-2026-118748: Unbounded Memory Allocation Denial of Service in ASP.NET Core Blazor Static-SSR

CVE-2026-118748 is a remote Denial of Service (DoS) vulnerability in Microsoft ASP.NET Core (.NET 11.0 preview releases prior to 11.0.0) and Microsoft Visual Studio 2026 (prior to 18.12.0). The flaw originates from unbounded resource allocation (CWE-770) within the Blazor static server-side rendering (static-SSR) validation pipeline, where dynamic or attacker-supplied form field identifiers are cached in a singleton-scoped memory structure without size limits or eviction policies. Unauthenticated remote attackers can exploit this condition over the network by sending repeated HTTP requests with unique field names, exhausting heap memory and terminating the host process via an unhandled OutOfMemoryException.

Alon Barad
Alon Barad
3 views•9 min read
•about 4 hours ago•CVE-2026-114150
5.9

CVE-2026-114150: Remote Information Disclosure via Uninitialized Pooled Memory in ASP.NET Core Response Buffering

CVE-2026-114150 is a network-accessible information disclosure vulnerability affecting Microsoft ASP.NET Core in .NET 11.0 preview releases and Microsoft Visual Studio 2026 prior to version 18.12.0. The flaw stems from the use of uninitialized resources (CWE-908) within response buffering components, specifically ResponseBufferingStream used by middleware such as HTTP Logging and Output Caching. Because rented memory segments from ArrayPool<byte> or MemoryPool<byte> are not cleared upon return or strictly bounded to the exact written byte count during subsequent reads, residual response payloads from earlier HTTP requests remain in the buffer tail. Downstream consumers or log sinks reading these buffers expose confidential cross-session data, including authentication tokens and personally identifiable information.

Amit Schendel
Amit Schendel
3 views•11 min read
•about 5 hours ago•CVE-2026-114146
9.0

CVE-2026-114146: Elevation of Privilege in ASP.NET Core SignalR Connection Dispatcher

An incorrect authorization vulnerability (CWE-863) exists in the ASP.NET Core SignalR HTTP Connection Dispatcher (`Microsoft.AspNetCore.Http.Connections`). The connection negotiation process failed to bind the authenticated caller identity to the generated connection state, and subsequent transport or message dispatch handlers failed to verify caller consistency. Consequently, an authenticated low-privilege attacker who obtains a valid connection identifier or token can inject messages into or hijack another user's SignalR session, achieving an elevation of privilege across security boundaries.

Alon Barad
Alon Barad
5 views•11 min read
•about 6 hours ago•CVE-2026-109478
7.5

CVE-2026-109478: Algorithmic Complexity Denial of Service in ASP.NET Core Header Parsing

CVE-2026-109478 is a network-accessible Denial of Service (DoS) vulnerability in ASP.NET Core caused by inefficient algorithmic complexity (CWE-407) when parsing comma-separated HTTP request headers. Prior to the patch, the internal helper method ParsingHelpers.GetHeaderSplit repeatedly called StringValues.Concat inside a loop iterating over each comma-separated token. Because StringValues allocates a new array of size k + 1 and copies all existing elements upon each concatenation, processing N tokens incurs O(N^2) time and space complexity. An unauthenticated remote attacker can send HTTP requests with headers containing thousands of short, comma-separated values to exhaust CPU cycles and induce severe Garbage Collection (GC) pauses, rendering the web application unresponsive.

Alon Barad
Alon Barad
6 views•11 min read