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

CVE-2026-114147: Denial of Service via Memory Leak in ASP.NET Core SignalR Redis Backplane

Amit Schendel
Amit Schendel
Senior Security Researcher

Nov 11, 2026·10 min read·0 visits

Executive Summary (TL;DR)

A case-sensitivity mismatch between per-connection group tracking (case-insensitive) and centralized Redis channel registries (case-sensitive), combined with a connection teardown race condition in Microsoft.AspNetCore.SignalR.StackExchangeRedis, allows unauthenticated remote attackers to cause unbounded memory leaks and Denial of Service.

CVE-2026-114147 is a high-severity Denial of Service (DoS) vulnerability affecting ASP.NET Core and specifically the Microsoft.AspNetCore.SignalR.StackExchangeRedis scale-out provider across .NET 8.0, 9.0, 10.0, and 11.0 preview releases. The vulnerability originates from a string comparison mismatch between internal per-connection group collections and the centralized Redis channel subscription registry, compounded by a race condition during connection teardown. Remote unauthenticated attackers can exploit this flaw to leave orphaned connection contexts and active Redis pub/sub listeners pinned in memory, leading to unbounded memory exhaustion and application process termination.

Vulnerability Overview

ASP.NET Core SignalR provides real-time web functionality that allows server-side code to push content to connected clients instantaneously. In multi-server deployments, SignalR relies on a scale-out backplane to coordinate message broadcasting, user invocations, and group management across distinct server nodes. The official Redis backplane implementation is distributed via the Microsoft.AspNetCore.SignalR.StackExchangeRedis NuGet package, which utilizes Redis Pub/Sub channels to route messages across the server farm.

Each SignalR server node maintains two distinct internal data structures to manage group memberships across the Redis backplane. First, each client connection (HubConnectionContext) holds an internal feature object (RedisFeature.Groups) that tracks the names of the groups the specific connection has joined. Second, the server maintains a centralized subscription manager (RedisSubscriptionManager) containing a concurrent dictionary (_subscriptions) that maps Redis Pub/Sub channel names to the collection of local client connections subscribed to each channel.

CVE-2026-114147 is a Denial of Service vulnerability classified under CWE-401 (Missing Release of Memory after Effective Lifetime) within this Redis scale-out provider. The vulnerability is caused by two interrelated defects: an inconsistency in string comparison rules between RedisFeature.Groups and RedisSubscriptionManager._subscriptions, and a race condition between connection termination and asynchronous subscription registration.

When exploited, these defects prevent the SignalR runtime from releasing HubConnectionContext instances and unsubscribing from Redis Pub/Sub channels after a client leaves a group or disconnects. An unauthenticated remote attacker can repeatedly trigger these conditions over standard WebSocket, Server-Sent Events (SSE), or Long Polling transports, exhausting heap memory and saturating thread pools on the target server.

Root Cause Analysis

The primary root cause of CVE-2026-114147 is a discrepancy in string comparer semantics between the per-connection group tracking set and the server-wide subscription store. In vulnerable versions of Microsoft.AspNetCore.SignalR.StackExchangeRedis, the per-connection group set in RedisFeature was initialized using a case-insensitive comparer (StringComparer.OrdinalIgnoreCase). Conversely, the centralized dictionary _subscriptions in RedisSubscriptionManager was initialized using a strict case-sensitive comparer (StringComparer.Ordinal).

When a client joins a group named "CustomGroup", the backplane adds "CustomGroup" to RedisFeature.Groups and registers the connection in RedisSubscriptionManager._subscriptions under the Redis channel key "prefix:Group:CustomGroup". If the client later requests to leave the group using a different casing, such as "customgroup", the removal routine checks RedisFeature.Groups first. Because RedisFeature.Groups uses OrdinalIgnoreCase, it matches and removes "CustomGroup" from the connection's tracking set.

Next, the runtime attempts to remove the connection from RedisSubscriptionManager._subscriptions using the newly supplied string "prefix:Group:customgroup". Because _subscriptions uses StringComparer.Ordinal, the key lookup fails to match the original entry "prefix:Group:CustomGroup". Consequently, the HubConnectionStore for the original channel is never updated, the connection count never reaches zero, and the Redis UNSUBSCRIBE command is never invoked. Even when the client later disconnects completely, the teardown routine iterates over RedisFeature.Groups to clean up remaining subscriptions; because the group was already removed from RedisFeature.Groups during the failed unsubscription attempt, the connection reference remains permanently pinned inside _subscriptions.

A secondary defect involves a race condition during connection teardown within HubConnectionHandler.OnConnectedAsync and RedisSubscriptionManager. In vulnerable versions, AbortAsync() was not guaranteed to complete prior to invoking HubLifetimeManager.OnDisconnectedAsync(). While RedisSubscriptionManager.AddSubscriptionAsync checked connection.ConnectionAborted.IsCancellationRequested to guard against adding subscriptions for closing connections, deferred execution of AbortAsync() allowed concurrent group join tasks to bypass this check. As a result, a background task or in-flight frame could insert a HubConnectionContext into _subscriptions concurrently with or after OnDisconnectedAsync() had already completed its cleanup pass, creating a second path to permanently orphaned connection objects.

Code Analysis

The official remediation was committed to the dotnet/aspnetcore repository in commits cc53379f74963c4509ddfa91845132146d7054aa and d94f9c231ee7e047c5c3c4cfdabe862274938faf. The patch addresses both the string comparer mismatch and the teardown synchronization race condition across three core components.

First, in src/SignalR/server/StackExchangeRedis/src/Internal/IRedisFeature.cs and RedisHubLifetimeManager.cs, the Groups collection in RedisFeature was modified to enforce case-sensitive comparison (StringComparer.Ordinal), matching the comparer used by RedisSubscriptionManager._subscriptions. Additionally, a boolean flag IsDisconnected was introduced on IRedisFeature to track the connection lifecycle state explicitly.

// src/SignalR/server/StackExchangeRedis/src/RedisHubLifetimeManager.cs
private sealed class RedisFeature : IRedisFeature
{
    // Fixed: Changed from StringComparer.OrdinalIgnoreCase to StringComparer.Ordinal
    // to prevent case drift between per-connection state and RedisSubscriptionManager.
    public HashSet<string> Groups { get; } = new HashSet<string>(StringComparer.Ordinal);
    public bool IsDisconnected { get; set; }
}

Second, RedisSubscriptionManager.cs was updated to synchronize group subscription additions and connection teardown using the internal SemaphoreSlim lock (_lock) and the new IsDisconnected flag. During disconnection, SetConnectionDisconnectedAndGetGroupNamesAsync acquires _lock, sets feature.IsDisconnected = true, and snapshots the active group names.

// src/SignalR/server/StackExchangeRedis/src/Internal/RedisSubscriptionManager.cs
public async Task<string[]> SetConnectionDisconnectedAndGetGroupNamesAsync(HubConnectionContext connection)
{
    await _lock.WaitAsync();
    try
    {
        var feature = connection.Features.GetRequiredFeature<IRedisFeature>();
        feature.IsDisconnected = true;
        return feature.Groups.ToArray();
    }
    finally
    {
        _lock.Release();
    }
}

Correspondingly, when AddGroupSubscriptionAsync acquires _lock to register a new group subscription, it inspects feature.IsDisconnected. If the connection has already transitioned to the disconnected state, the method aborts the registration immediately before modifying feature.Groups or _subscriptions.

// Inside AddGroupSubscriptionAsync after acquiring _lock:
var feature = connection.Features.GetRequiredFeature<IRedisFeature>();
// Fixed: Reject late subscription attempts arriving during or after disconnect teardown.
if (feature.IsDisconnected)
{
    return;
}
if (!feature.Groups.Add(id))
{
    return;
}

Third, in src/SignalR/server/Core/src/HubConnectionHandler.cs, the finally block of OnConnectedAsync was updated to explicitly await connectionContext.AbortAsync() prior to calling connectionContext.Cleanup() and tearing down the lifetime manager.

--- a/src/SignalR/server/Core/src/HubConnectionHandler.cs
+++ b/src/SignalR/server/Core/src/HubConnectionHandler.cs
@@ -151,6 +151,9 @@ public override async Task OnConnectedAsync(ConnectionContext connection)
         }
         finally
         {
+            // Ensure the connection is aborted before lifetime manager teardown.
+            await connectionContext.AbortAsync();
+
             connectionContext.Cleanup();
 
             Log.ConnectedEnding(_logger);

> [!NOTE] > Fix Completeness Assessment: The patch resolves both the casing discrepancy and the concurrency race. By unifying both collections on StringComparer.Ordinal and gating all mutations to IRedisFeature.Groups and _subscriptions behind the same SemaphoreSlim instance (_lock), state desynchronization between the connection feature and the subscription store is no longer possible.

Exploitation

Exploiting CVE-2026-114147 requires network access to an ASP.NET Core SignalR endpoint configured to use the Microsoft.AspNetCore.SignalR.StackExchangeRedis backplane. For the case-mismatch vector, the target SignalR Hub must expose methods that allow connected clients to join and leave groups using caller-supplied or caller-influenced strings without enforcing case normalization. For the race-condition vector, the Hub only needs to trigger group additions during connection initialization or allow rapid group join invocations prior to transport closure.

An attack leveraging the string comparer mismatch proceeds through the following sequence:

  1. Connection Initialization: The client initiates a SignalR negotiation and establishes a transport session (WebSocket, SSE, or Long Polling) with the target Hub.
  2. Group Subscription: The client invokes a Hub method that calls Groups.AddToGroupAsync(Context.ConnectionId, "TargetGroup_1") using mixed or uppercase characters. The server allocates a HubConnectionStore entry in _subscriptions["prefix:Group:TargetGroup_1"] and subscribes to the corresponding Redis channel.
  3. Case-Mismatched Unsubscription: The client invokes the Hub's leave method passing lowercase characters: Groups.RemoveFromGroupAsync(Context.ConnectionId, "targetgroup_1"). The server removes "TargetGroup_1" from RedisFeature.Groups, but fails to remove the connection from _subscriptions["prefix:Group:TargetGroup_1"].
  4. Iteration and Disconnection: The client repeats steps 2 and 3 across thousands of unique group names (e.g., "TargetGroup_2", "TargetGroup_3") over the same connection or across multiple short-lived connections, and then closes the transport connection.

Because each mismatched unsubscription detaches the group identifier from RedisFeature.Groups while leaving the HubConnectionContext reference inside RedisSubscriptionManager._subscriptions, the .NET garbage collector is prevented from reclaiming the HubConnectionContext instance, its associated network buffers, and connection state features. Furthermore, each distinct group name leaves an active subscription registered on the Redis Pub/Sub connection.

In addition to direct heap exhaustion, this state causes message fan-out amplification. Whenever legitimate messages are broadcast to an affected group or when Redis Pub/Sub events fire on the leaked channels, the server iterates through all retained HubConnectionStore entries and attempts to serialize and write payloads to the aborted connections, consuming CPU cycles and saturating the .NET thread pool.

Impact Assessment

The security impact of CVE-2026-114147 is a complete Denial of Service of the affected ASP.NET Core application process. Microsoft and NVD assigned a CVSS v3.1 base score of 7.5 (High) with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H.

The vulnerability is remotely exploitable over the network (AV:N) with low attack complexity (AC:L). Unless the SignalR Hub enforces authentication via the [Authorize] attribute prior to connection establishment or method invocation, no privileges (PR:N) or user interaction (UI:N) are required. The flaw does not allow unauthorized reading (C:N) or modification (I:N) of application memory or data.

However, the availability impact is high (A:H). As orphaned HubConnectionContext objects and HubConnectionStore dictionaries accumulate in the Gen 2 managed heap and Large Object Heap (LOH), the hosting process experiences sustained memory growth until the operating system or container orchestrator (such as Kubernetes OOMKiller) terminates the process with an Out-Of-Memory condition.

In multi-node deployments sharing a single Redis backplane, the impact extends to backplane throughput degradation. Because the UNSUBSCRIBE command is never sent to Redis for orphaned group channels, the Redis server continues to route Pub/Sub messages to affected ASP.NET Core nodes for groups that no longer have active local clients, increasing network bandwidth utilization and Redis CPU load across the cluster.

Remediation

To remediate CVE-2026-114147, upgrade the Microsoft.AspNetCore.SignalR.StackExchangeRedis NuGet package and the underlying .NET Runtime and SDK to the patched versions released in the November 2026 servicing updates:

  • Microsoft.AspNetCore.SignalR.StackExchangeRedis: Upgrade to version 10.0.15 (or the matching servicing version for your target framework: 8.0.34 for .NET 8, 9.0.23 for .NET 9).
  • .NET 8.0 Runtime / SDK: Upgrade to version 8.0.34 or later.
  • .NET 9.0 Runtime / SDK: Upgrade to version 9.0.23 or later.
  • .NET 10.0 Runtime / SDK: Upgrade to version 10.0.15 or later.
  • .NET 11.0 Runtime / SDK: Upgrade to version 11.0.0 (GA/RTM) or later.
  • Microsoft Visual Studio: Upgrade Visual Studio 2022 to 17.14.45, and Visual Studio 2026 to 18.11.4 or the 18.12.0 servicing update.

> [!IMPORTANT] > Because HubConnectionHandler.cs is part of the shared ASP.NET Core framework (Microsoft.AspNetCore.App), applications must update both the hosting runtime (to receive the AbortAsync() ordering fix) and the Microsoft.AspNetCore.SignalR.StackExchangeRedis package reference (to receive the RedisSubscriptionManager and RedisFeature fixes).

For environments where immediate package and runtime upgrades cannot be deployed, developers can mitigate the case-mismatch vector at the application layer by canonicalizing all group names before passing them to IGroupManager methods:

public class ChatHub : Hub
{
    public async Task JoinRoom(string roomName)
    {
        if (string.IsNullOrWhiteSpace(roomName)) return;
        // Normalize casing to prevent ordinal vs. case-insensitive mismatch
        string normalizedRoom = roomName.Trim().ToUpperInvariant();
        await Groups.AddToGroupAsync(Context.ConnectionId, normalizedRoom);
    }
 
    public async Task LeaveRoom(string roomName)
    {
        if (string.IsNullOrWhiteSpace(roomName)) return;
        string normalizedRoom = roomName.Trim().ToUpperInvariant();
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, normalizedRoom);
    }
}

In addition to input canonicalization, administrators should enforce authentication ([Authorize]) on SignalR Hubs where business logic permits, and configure connection rate limiting at the reverse proxy, ingress controller, or ASP.NET Core rate-limiting middleware layer to restrict rapid connect/disconnect cycling from single IP addresses.

Official Patches

MicrosoftMicrosoft Security Update Guide Advisory for CVE-2026-114147
Microsoft / .NETASP.NET Core v8.0.34 Release Notes
Microsoft / .NETASP.NET Core v9.0.23 Release Notes
Microsoft / .NETASP.NET Core v10.0.15 Release Notes
Microsoft / .NETASP.NET Core v11.0.0 Release Notes

Fix Analysis (2)

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.SignalR.StackExchangeRedisMicrosoft .NET 8.0Microsoft .NET 9.0Microsoft .NET 10.0Microsoft .NET 11.0Microsoft Visual Studio 2022 version 17.14Microsoft Visual Studio 2026 version 18.11Microsoft Visual Studio 2026 version 18.12

Affected Versions Detail

Product
Affected Versions
Fixed Version
Microsoft.AspNetCore.SignalR.StackExchangeRedis
Microsoft
< 10.0.1510.0.15
.NET 8.0
Microsoft
>= 8.0.0, < 8.0.348.0.34
.NET 9.0
Microsoft
>= 9.0.0, < 9.0.239.0.23
.NET 10.0
Microsoft
>= 10.0.0, < 10.0.1510.0.15
.NET 11.0
Microsoft
>= 11.0.0-preview.1, < 11.0.011.0.0
Microsoft Visual Studio 2022 version 17.14
Microsoft
>= 17.14.0, < 17.14.4517.14.45
Microsoft Visual Studio 2026 version 18.11
Microsoft
>= 18.11.0, < 18.11.418.11.4
Microsoft Visual Studio 2026 version 18.12
Microsoft
18.12.018.12.0
AttributeDetail
CVE IDCVE-2026-114147
CWE ClassificationCWE-401 (Missing Release of Memory after Effective Lifetime)
CVSS v3.1 Score7.5 High (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
Affected ComponentMicrosoft.AspNetCore.SignalR.StackExchangeRedis
Attack VectorNetwork (WebSocket / SSE / Long Polling)
Primary ImpactDenial of Service via Unbounded Memory Leak
Exploit StatusUnproven (No public PoCs or active exploitation)
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-401
Missing Release of Memory after Effective Lifetime

The product does not sufficiently track or release allocated memory resources after they have reached the end of their effective operational lifecycle, resulting in an unbounded accumulation of resources (memory leak).

Vulnerability Timeline

Fix commits merged into dotnet/aspnetcore (PR #65072 and PR #64560)
2026-10-19
CVE-2026-114147 published by Microsoft and NVD with CVSS 7.5 High severity
2026-11-10
CVE record updated with complete affected product and version matrices
2026-11-11

References & Sources

  • [1]Microsoft Security Update Guide: CVE-2026-114147
  • [2]Official CVE Record: CVE-2026-114147
  • [3]National Vulnerability Database (NVD): CVE-2026-114147
  • [4]GitHub Commit cc53379f74963c4509ddfa91845132146d7054aa (PR #65072)
  • [5]GitHub Commit d94f9c231ee7e047c5c3c4cfdabe862274938faf (PR #64560)
  • [6]ASP.NET Core v8.0.34 Release
  • [7]ASP.NET Core v9.0.23 Release
  • [8]ASP.NET Core v10.0.15 Release
  • [9]ASP.NET Core v11.0.0 Release
  • [10]Shodan CVE Database Entry: CVE-2026-114147

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

•about 1 hour ago•CVE-2026-114156
6.5

CVE-2026-114156: Path Equivalence Security Feature Bypass in Microsoft ASP.NET Core

CVE-2026-114156 is an improper resolution of path equivalence vulnerability (CWE-41) in Microsoft ASP.NET Core affecting .NET 11.0 preview releases and Microsoft Visual Studio 2026. The vulnerability stems from a discrepancy between how path prefix validation helpers (such as PathString.StartsWithSegments) and downstream routing mechanisms handle alternate path separators and percent-encoded characters. An unauthenticated remote attacker can exploit this mismatch over the network to bypass path-based authorization middleware and access restricted endpoints.

Amit Schendel
Amit Schendel
4 views•8 min read
•about 2 hours ago•CVE-2026-114157
7.5

CVE-2026-114157: Local Privilege Escalation via Race Condition in ASP.NET Core Kestrel Named Pipes Transport

CVE-2026-114157 is a high-severity local privilege escalation and security feature bypass vulnerability affecting ASP.NET Core on Microsoft Windows. The flaw resides in the Kestrel web server's Named Pipes transport layer (Microsoft.AspNetCore.Server.Kestrel.Transport.NamedPipes) and stems from a race condition (CWE-362) during broken pipe error recovery. When an active connection throws an IOException during handshake acceptance, the connection listener previously disposed of the broken NamedPipeServerStream instance before acquiring a replacement stream from its internal pool. This sequence created a momentary window where zero server instances of the named pipe existed in the Windows Named Pipe File System (NPFS). A local, low-privileged attacker can exploit this timing window to create a named pipe with the identical name and a permissive Discretionary Access Control List (DACL), hijacking subsequent inter-process communications and escalating privileges across security boundaries.

Amit Schendel
Amit Schendel
6 views•11 min read
•about 3 hours ago•CVE-2026-124194
6.5

CVE-2026-124194: Forced Authentication and NetNTLMv2 Credential Leakage in Microsoft Office Outlook

CVE-2026-124194 is a forced authentication and spoofing vulnerability in Microsoft Office Outlook caused by a missing user interface warning before dereferencing remote network paths (CWE-356). By embedding an attacker-controlled Universal Naming Convention (UNC) path within MAPI message properties such as PidLidReminderFileParameter, an unauthenticated remote attacker can force a victim's system to initiate an outbound SMB or WebDAV connection upon opening or previewing a crafted message. This automatic authentication handshake leaks the user's NetNTLMv2 hash, enabling offline password cracking or real-time NTLM relay attacks. The vulnerability was exploited in the wild as a zero-day prior to its remediation in Microsoft's November 2026 Patch Tuesday updates and is listed in the CISA Known Exploited Vulnerabilities (KEV) catalog.

Alon Barad
Alon Barad
14 views•10 min read
•about 3 hours ago•CVE-2026-114154
7.5

CVE-2026-114154: Denial of Service in ASP.NET Core HttpSys Request Header Processing

CVE-2026-114154 is a high-severity Denial of Service (DoS) and uncontrolled resource consumption vulnerability in the Microsoft.AspNetCore.Server.HttpSys component of ASP.NET Core. When processing an HTTP request that simultaneously contains a chunked Transfer-Encoding header, a Content-Length header, and an explicit X-Content-Length header, the server throws an unhandled ArgumentException during header normalization. In certain versions, subsequent exception handling attempts to dereference a disposed native request context, aborting error response dispatch and leaking unmanaged HTTP.sys request structures.

Amit Schendel
Amit Schendel
4 views•9 min read
•about 4 hours ago•CVE-2026-120778
7.3

CVE-2026-120778: Local Elevation of Privilege via Insecure Temporary Directory Handling and MSBuild Response File Hijacking in Microsoft .NET Aspire CLI

A local elevation of privilege vulnerability exists in the Microsoft .NET Aspire CLI (`Aspire.Cli`) versions 13.5.4 prior to 13.6.5. When executing SDK management commands (`aspire sdk generate`, `aspire sdk dump`, and `aspire sdk export`), the CLI creates temporary project directories inside the shared operating system temporary folder (such as `/tmp` on Unix-like systems) without restricting directory permissions or disabling MSBuild automatic response file resolution. A local, low-privileged attacker on a multi-user system can place a crafted `Directory.Build.rsp` file in the shared temporary directory hierarchy. When a victim user executes an affected Aspire CLI command, MSBuild traverses upward, ingests the attacker-controlled response file, and executes arbitrary commands in the security context of the victim user.

Alon Barad
Alon Barad
4 views•10 min read
•about 5 hours ago•CVE-2026-120792
7.3

CVE-2026-120792: Local Information Disclosure via Temporary File Logging in Microsoft .NET Aspire CLI

CVE-2026-120792 is a high-severity local information disclosure vulnerability in the Microsoft .NET Aspire CLI (Aspire.Cli) affecting versions 13.5.4 prior to 13.6.5. The flaw stems from the insertion of sensitive information into a shared temporary log file (CWE-532) combined with insecure temporary file creation (CWE-377) within the DeprecatedMcpCommandScanner component. During agent configuration scanning, the CLI unconditionally appends internal workspace paths and the first 200 characters of Model Context Protocol (MCP) agent configuration files to a statically named file in the system temporary directory. On multi-user systems, unprivileged local users can read this file to harvest API keys, authentication tokens, and internal service endpoints.

Alon Barad
Alon Barad
4 views•9 min read