CVE-2026-114155: CVE-2026-114155: Local Elevation of Privilege via TOCTOU Race Condition in Microsoft .NET dotnet-watch
CVE-2026-114155: Local Elevation of Privilege via TOCTOU Race Condition in Microsoft .NET dotnet-watch Vulnerability ID: CVE-2026-114155 CVSS Score: 7.5 Published: 2026-11-11 CVE-2026-114155 is a local elevation of
CVE-2026-114155: Local Elevation of Privilege via TOCTOU Race Condition in Microsoft .NET dotnet-watch
Vulnerability ID: CVE-2026-114155
CVSS Score: 7.5
Published: 2026-11-11
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.
TL;DR
A TOCTOU race condition (CWE-367) in the Microsoft .NET dotnet-watch utility on Linux and macOS allows local attackers to overwrite temporary .slnx solution files in /tmp before MSBuild processes them, leading to local privilege escalation.
Technical Details
- Vulnerability Type: CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition
- Attack Vector: Local (Shared /tmp directory on Linux and macOS)
- CVSS v3.1 Score: 7.5 HIGH (CVSS:3.1/AV:L/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:H)
- Affected Component: Microsoft .NET SDK dotnet-watch (HotReloadDotNetWatcher)
- Security Impact: Local Elevation of Privilege via arbitrary MSBuild code execution
- Exploit Status: Unproven (No public PoC or active exploitation)
- CISA KEV Status: Not Listed
Affected Systems
- Microsoft .NET 10.0 on Linux
- Microsoft .NET 10.0 on macOS
- Microsoft .NET 11.0 on Linux
- Microsoft .NET 11.0 on macOS
- Microsoft.DotNet.HotReload.Watch.Aspire
-
Microsoft .NET 10.0 (Linux & macOS): >= 10.0.0, < 10.0.404 (Fixed in:
10.0.404) -
Microsoft .NET 11.0 (Linux & macOS): >= 11.0.0-preview.1, < 11.0.100 (Fixed in:
11.0.100) -
Microsoft.DotNet.HotReload.Watch.Aspire: >= 10.0.300, < 11.0.100 (Fixed in:
11.0.100)
Code Analysis
Commit: c46253a
Introduce TemporaryFileManager to securely create and lock temporary files in a user-private directory during dotnet-watch execution.
--- a/src/sdk/src/Dotnet.Watch/Watch/HotReload/HotReloadDotNetWatcher.cs
+++ b/src/sdk/src/Dotnet.Watch/Watch/HotReload/HotReloadDotNetWatcher.cs
@@ -1144,7 +1144,8 @@ async Task<bool> BuildAsync(BuildAction action, string? targetFramework, DeviceI
}
else if (projectPaths is not [])
{
- var solutionFile = Path.Combine(Path.GetTempFileName() + ".slnx");
+ // Keep the file open and allow other processes to read it (but not modify) after the content is written:
+ using var solutionFile = _context.TemporaryFileManager.Create(".slnx", FileShare.Read);
var solutionElement = new XElement("Solution");
foreach (var projectPath in projectPaths)
@@ -1153,25 +1154,11 @@ async Task<bool> BuildAsync(BuildAction action, string? targetFramework, DeviceI
}
var doc = new XDocument(solutionElement);
- doc.Save(solutionFile);
+ doc.Save(solutionFile.Stream);
- try
+ if (!await BuildFileOrProjectOrSolutionAsync(solutionFile.Stream.Name, targetFramework, device, action, cancellationToken))
{
- if (!await BuildFileOrProjectOrSolutionAsync(solutionFile, targetFramework, device, action, cancellationToken))
- {
- return false;
- }
- }
- finally
- {
- try
- {
- File.Delete(solutionFile);
- }
- catch
- {
- // ignore
- }
+ return false;
}
}
Commit: 032f564
Merge pull request 66316 from msrc-temp-10.0.4xx into internal release branch.
Mitigation Strategies
- Upgrade Microsoft .NET 10.0 and .NET 11.0 SDKs to the latest patched versions.
- Configure per-user isolated temporary directories on Linux and macOS using the TMPDIR environment variable.
- Avoid executing dotnet-watch with elevated privileges (such as root or sudo) on shared multi-user systems.
- Enable Linux kernel protections for regular files in sticky world-writable directories (fs.protected_regular=2).
Remediation Steps:
- Identify all Linux and macOS developer workstations and build servers with Microsoft .NET 10.0 (< 10.0.404) or .NET 11.0 (< 11.0.100) installed.
- Upgrade Microsoft .NET 10.0 SDK to 10.0.404 (Runtime 10.0.15) or Microsoft .NET 11.0 SDK to 11.0.100 (Runtime 11.0.0).
- Update any project dependencies on Microsoft.DotNet.HotReload.Watch.Aspire to version 11.0.100 or later.
- If immediate patching is blocked, configure user profiles to export TMPDIR="$HOME/.tmp" with 0700 directory permissions.
References
- Microsoft Security Response Center (MSRC) Advisory: CVE-2026-114155
- Official CVE Record (CVE.org): CVE-2026-114155
- Fix Commit in dotnet/dotnet (c46253a634a2725fd34820ad8a36a3f106f5d01d)
- Merge Pull Request Commit in dotnet/dotnet (032f564872d408f03fba11c8d03e5cd7386164cd)
- GitHub Pull Request 10885 (dotnet/dotnet)
- GitHub Pull Request 10886 (dotnet/dotnet)
- .NET Core Release Tag v10.0.15
- .NET Core Release Tag v11.0.0
- .NET Release Tag v10.0.404
- .NET Release Tag v11.0.100
Read the full report for CVE-2026-114155 on our website for more details including interactive diagrams and full exploit analysis.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.