← Back to Feed CACHED · 2026-10-26 17:42:35 · CACHE_KEY CVE-2026-102870
CVE-2026-102870 · CWE-94 · Disclosed 2026-10-13

ASP.NET Core Blazor WebAssembly debug proxy code injection via unescaped expression evaluation

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

A booby-trapped business card that only detonates when the detective picks it up with tweezers under a magnifying glass

CVE-2026-102870 is a code-injection flaw in the Blazor WebAssembly debug proxy (BrowserDebugHost) bundled in Microsoft.AspNetCore.Components.WebAssembly.Server and .DevServer. The debug proxy evaluates developer expressions by generating and compiling C# source on the fly — but it embeds application-originated values (ToString() results, descriptions, class names) into that generated source *without consistent escaping*. If a malicious value lands in a field a developer inspects, the payload breaks out of the generated string literal and executes arbitrary code on the developer's machine. Affected versions are Microsoft.AspNetCore.Components.WebAssembly.Server 10.0.0–10.0.13 and 11.0.0-preview.1 through 11.0.0-rc.2. The initial fix shipped October 13 in .NET 10.0.13 was incomplete; the corrected release is .NET 10.0.14 (October 25, 2026). Visual Studio 2022 v17.14 and Visual Studio 2026 v18.10+ are also affected via the bundled SDK.

Microsoft rates this Important / 8.8 HIGH — and the CVSS math is technically valid (AV:N/AC:L/PR:N/UI:R), but the score dramatically overstates real-world risk. The AV:N reflects that malicious data arrives over the network, not that the debug proxy itself is internet-reachable. Exploitation requires a triple-gated user interaction: (1) attacker-controlled data present in the debugged app, (2) a Blazor WASM debug session running against that data, and (3) the developer actively evaluating an expression containing the poisoned value. This is a development-time tooling bug, not a production attack surface. No production ASP.NET Core server is vulnerable. The realistic severity is MEDIUM ~5.5 once you account for the narrow developer-only exposure and the absence of any exploitation activity.

"Dev-tooling vuln in Blazor WASM debug proxy; only fires during active debug sessions with poisoned data"
02 · The Attack Path

5 steps from start to impact.

STEP 01

Poison the data source

The attacker injects a crafted string — containing a C# code injection payload — into a data source the target Blazor WebAssembly application consumes. This could be a database field, a REST API response, a CMS entry, or any user-controlled value that surfaces as an object property, ToString() result, or class name. No special tooling is needed beyond access to the data source.
Conditions required:
  • Write access to a data source consumed by the target Blazor WASM app
  • Knowledge that the target team develops a Blazor WebAssembly application
Where this breaks in practice:
  • Attacker needs to know (or guess) that the target team uses Blazor WASM specifically, not Blazor Server or another SPA framework
  • The poisoned value must land in a field a developer would plausibly inspect during debugging — not buried in an ignored column
STEP 02

Developer launches Blazor WASM debug session

A developer on the target team opens the Blazor WebAssembly project in Visual Studio (2022 v17.14 or 2026 v18.x) or VS Code with the .NET 10 SDK and starts a debug session. The BrowserDebugHost debug proxy spins up and begins proxying CDP (Chrome DevTools Protocol) traffic between the IDE and the browser running the WASM app.
Conditions required:
  • Developer is using a vulnerable .NET 10.0.0–10.0.13 SDK or .NET 11 preview/RC < rc.3
  • Developer launches a debug (F5) session, not a no-debug (Ctrl+F5) run
Where this breaks in practice:
  • Only Blazor WebAssembly developers are affected — Blazor Server, MVC, Razor Pages, and minimal API developers are out of scope
  • The debug proxy only runs during active debugging; production dotnet run or dotnet publish never invokes it
  • Many orgs use containers or remote dev environments where the debug proxy may not be active
STEP 03

Application loads the poisoned data

During the debug session, the Blazor WASM app fetches data from the poisoned source. The malicious object/value is loaded into the browser's WASM runtime memory. At this point, nothing has executed on the developer's machine yet — the payload is dormant in the browser.
Conditions required:
  • The Blazor app's workflow during the debug session must hit the poisoned data path
  • The debug session must be connected to the data source containing the malicious data (not a sanitized test database)
Where this breaks in practice:
  • Many teams use seed/mock data for local debugging, not live production databases
  • API gateways or ORMs may truncate or sanitize the special characters needed for the injection
STEP 04

Developer evaluates a tainted expression

The developer hits a breakpoint (or pauses execution) and inspects the malicious object — via the Watch window, hovering over a variable, or typing in the Immediate window. The IDE sends a CDP Runtime.evaluate request to the debug proxy. The proxy takes the tainted value and embeds it into dynamically generated C# source code for compilation.
Conditions required:
  • Developer must actively interact with the debugger near the tainted data
  • The specific expression evaluated must surface the malicious value (e.g., viewing the object's ToString() or a property that contains the payload)
Where this breaks in practice:
  • This requires conscious, manual action by the developer — it does not trigger automatically on breakpoint hit unless auto-expand is configured for the tainted object
  • The developer would need to inspect the specific field containing the payload, which may not be obvious or interesting during normal debugging
Detection/coverage: EDR may flag unexpected child process spawning from devenv.exe or dotnet during a debug session, but this would be novel detection logic not commonly deployed
STEP 05

Code injection and execution on developer machine

Because the debug proxy does not properly escape the tainted value, the attacker's payload breaks out of the generated string literal in the C# source. The Roslyn compiler compiles and executes the injected code in the context of the debug host process on the developer's machine, running with the developer's user privileges. The attacker achieves arbitrary code execution.
Conditions required:
  • All prior steps must chain successfully
  • The injected C# must be syntactically valid to compile
Where this breaks in practice:
  • The generated code context constrains what syntax will compile — the attacker needs to craft a payload that cleanly escapes the string literal AND produces valid C# in the surrounding generated code
  • Character encoding, escaping layers, or IDE-specific serialization may mangle the payload before it reaches the code generation step
Detection/coverage: Endpoint Detection: process tree anomalies (e.g., BrowserDebugHost.exe spawning cmd.exe, powershell.exe, or network connections to unexpected hosts). No known scanner signature or Nuclei template exists for this CVE.
03 · Compensating Control

1
MEDIUM 5.5→IGNORE 0.0
SEVERITY REDUCED
Update .NET SDK to 10.0.14+ and NuGet packages to patched versions — The definitive fix. Update the .NET 10 SDK to 10.0.14 (released October 25, 2026) and ensure Microsoft.AspNetCore.Components.WebAssembly.Server and .DevServer NuGet references are ≥ 10.0.14. For .NET 11 preview users, update to rc.3. This is a MEDIUM verdict — no noisgate mitigation SLA applies. Target the 365-day noisgate remediation SLA window, though updating developer tooling is typically low-friction and can be done sooner via normal SDK update cadence.
2
MEDIUM 5.5→LOW 2.5
SEVERITY REDUCED
Debug only against sanitized or seed data, never live/untrusted sources — If the Blazor WASM app's debug sessions always connect to a controlled seed database or mock API with known-clean data, the attacker has no vector to inject a malicious payload into the code generation path. This is a best practice regardless of this CVE. Implement as standard development hygiene within 365 days.
3
MEDIUM 5.5→IGNORE 0.0
SEVERITY REDUCED
Update Visual Studio to latest servicing release — Visual Studio 2022 v17.14.43+ and Visual Studio 2026 patched releases bundle the corrected BrowserDebugHost. Enterprise Visual Studio deployments managed via VSIX or admin update channels should push this as part of normal tooling updates within the 365-day remediation window.
4
MEDIUM 5.5→MEDIUM 4.5
Monitor for anomalous child processes from BrowserDebugHost.exe and devenv.exe — Configure EDR to alert on BrowserDebugHost.exe spawning unexpected child processes (cmd.exe, powershell.exe, net.exe, whoami.exe) or making outbound network connections to non-localhost destinations during debug sessions. This provides detection-in-depth but does not prevent exploitation.
What doesn't work
  • WAF / NGFW rules — The debug proxy runs on localhost during development. No network traffic passes through perimeter or application firewalls. WAF rules cannot inspect or block this attack path.
  • Production .NET runtime patching — Updating the .NET runtime on production servers has zero effect on this CVE. The vulnerable component (BrowserDebugHost) is a development-time tool that is never deployed to production.
  • Network segmentation of production databases — While generally good practice, this only helps if the *development* data source is also segmented. The attack targets the dev environment, not production infrastructure.
04 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNone observed. Microsoft rates exploitation as "Less Likely". Not listed on CISA KEV. No campaigns or threat actor attribution identified.
Proof-of-Concept AvailabilityNo public PoC found. No repositories on GitHub named after CVE-2026-102870. Not indexed on pocindex.io. No Nuclei template, ExploitDB entry, or Metasploit module. The attack requires crafting a C# injection payload that survives the debug proxy's code generation context — non-trivial but achievable by a skilled researcher.
EPSS Score0.91% (59.6th percentile) — below the 6% threshold commonly used to flag likely-exploited vulns. Consistent with "development tooling bug unlikely to see mass exploitation."
CISA KEV StatusNot listed. No federal mandate to patch on an emergency timeline.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H — base 8.8, temporal 7.7 (E:U/RL:O/RC:C). The AV:N is technically correct (data arrives over the network) but misleading: the debug proxy is not a remotely-reachable service. UI:R understates the interaction — it requires a specific debugging workflow, not just clicking a link.
Affected VersionsMicrosoft.AspNetCore.Components.WebAssembly.Server and .DevServer 10.0.0–10.0.13 (.NET 10), 11.0.0-preview.1 through 11.0.0-rc.2 (.NET 11 preview). Also bundled in Visual Studio 2022 v17.14 (<17.14.43) and Visual Studio 2026 v18.10/18.11/18.12.
Fixed Versions.NET SDK 10.0.14 (runtime 10.0.14, released October 25, 2026). .NET 11 11.0.0-rc.3.26522.148. NuGet package Microsoft.AspNetCore.Components.WebAssembly.Server ≥ 10.0.14. Note: the October 13 release (10.0.13) had an incomplete fix — the corrected BrowserDebugHost packaging shipped October 25.
Scanning / ExposureZero internet-facing attack surface. The Blazor WASM debug proxy (BrowserDebugHost) listens only on localhost during debug sessions and is never deployed to production. Shodan/Censys/GreyNoise scans are irrelevant for this CVE.
Disclosure TimelineOctober 13, 2026: Initial disclosure + incomplete fix in .NET 10.0.13. October 25, 2026: Corrected out-of-band release in .NET 10.0.14 with fixed BrowserDebugHost packaging.
Reporter / CreditsNot publicly attributed in the Microsoft advisory or dotnet/announcements issue.

Sources.

  1. Microsoft Security Advisory (dotnet/announcements)
  2. .NET 10.0.14 Release Notes (October 25, 2026)
  3. .NET October 2026 Out-of-Band Security Updates
  4. GitLab Advisory Database — NuGet Advisory
  5. Red Hat CVE Page — CVE-2026-102870
  6. Strix AI — CVE-2026-102870 Analysis
  7. SentinelOne Vulnerability Database
05 · The Call

Final Verdict
↓ DOWNGRADED to MEDIUM (5.5/10)

Why this verdict

  • Development-only attack surface (major downgrade): This vulnerability exists exclusively in the Blazor WebAssembly debug proxy, a component that runs only during active development debugging sessions. Production ASP.NET Core servers, containers, and published applications never invoke BrowserDebugHost. The entire production installed base of ASP.NET Core — the population that drives the vendor's HIGH rating — is completely unaffected.
  • Triple-gated user interaction (major downgrade): CVSS scores UI:R as a single bit, but this chain requires three independent user actions: (1) running a Blazor WASM debug session specifically, (2) against a data source containing the attacker's payload, (3) and then manually evaluating an expression that surfaces the poisoned value. Each gate independently narrows the exploitation window. This is categorically different from "user clicks a link."
  • Niche component scope (moderate downgrade): Blazor WebAssembly is a subset of the ASP.NET Core ecosystem. Among .NET developers, Blazor WASM adoption is a fraction of total ASP.NET Core usage. The affected developer population is small, and only those debugging against untrusted/live data sources are in the blast radius.
  • No exploitation activity (supporting factor): Microsoft rates exploitation "Less Likely." EPSS is 0.91%. No public PoC exists. No KEV listing. No observed campaigns. The initial fix was incomplete, suggesting limited external pressure to weaponize.
  • Role multiplier: The Blazor WASM debug proxy runs exclusively on developer workstations (low-value role by infrastructure standards). It does not exist on domain controllers, edge appliances, CI/CD runners (which don't run interactive debug sessions), hypervisors, backup infrastructure, or any other high-value role in the catalog. A successful exploit yields code execution on one developer's machine — host-level blast radius, not domain/fleet/supply-chain scale. A sophisticated attacker could pivot from a compromised dev machine to source code or CI credentials, but that requires additional steps outside this vulnerability's scope. The high-value-role floor does not apply.

Why not higher?

The CVSS 8.8 / HIGH vendor rating would be appropriate if this were a production web application vulnerability exploitable by any user visiting a website. It is not. The debug proxy has zero production deployment footprint, zero internet-facing attack surface, and requires a specific multi-step developer interaction during an active debugging session. Upgrading to HIGH would conflate a development tooling quirk with a remotely exploitable production service, misallocating enterprise patching resources away from actual perimeter or server-side risks.

Why not lower?

Code execution on a developer machine is not trivial. Developers typically have access to source code repositories, CI/CD pipeline credentials, package publishing tokens, and elevated permissions in development infrastructure. A targeted attacker (e.g., poisoning a shared development database or a third-party API consumed during development) could use this as an initial access vector to eventually compromise a build pipeline or inject malicious code into a release artifact. The impact on a single successfully exploited machine is genuinely high (C:H/I:H/A:H), preventing a drop to LOW.

06 · Verification

Crowdsourced verification payload.

Run on each developer workstation or build server where Blazor WebAssembly projects are developed. No admin privileges required — just read access to project directories. Invoke: powershell -ExecutionPolicy Bypass -File Check-CVE2026102870.ps1 -SearchPath C:\src

noisgate-verify.ps1
POWERSHELLREAD-ONLYSAFE
#Requires -Version 5.1
<#
  Check-CVE2026102870.ps1
  Detects vulnerable Blazor WebAssembly debug proxy (CVE-2026-102870)
  Exit 0 = PATCHED, Exit 1 = VULNERABLE, Exit 2 = UNKNOWN
#>
param([string]$SearchPath = '.')

$VulnPkgs = @(
  'Microsoft.AspNetCore.Components.WebAssembly.Server',
  'Microsoft.AspNetCore.Components.WebAssembly.DevServer'
)
$SafeVer10 = [version]'10.0.14'
$found = $false
$vuln  = $false

# --- Check 1: .NET SDK version ---
Write-Host '[*] Checking installed .NET SDKs...'
try {
  $sdks = & dotnet --list-sdks 2>$null
  foreach ($line in $sdks) {
    if ($line -match '^(10\.0\.(\d+))') {
      $found = $true
      $sdkPatch = [int]$Matches[2]
      # SDK 10.0.114 ships runtime 10.0.14; SDK patch >= 403 also maps to fixed runtime
      if ($sdkPatch -lt 114 -and $sdkPatch -lt 403) {
        Write-Host "[!] VULNERABLE SDK: $($Matches[1])" -ForegroundColor Red
        $vuln = $true
      } else {
        Write-Host "[+] Patched SDK: $($Matches[1])" -ForegroundColor Green
      }
    }
    if ($line -match '^(11\.0\.0-(preview|rc\.[12]))') {
      $found = $true
      Write-Host "[!] VULNERABLE SDK (pre-rc.3): $($Matches[1])" -ForegroundColor Red
      $vuln = $true
    }
  }
} catch { Write-Host '[?] dotnet CLI not found' -ForegroundColor Yellow }

# --- Check 2: NuGet package references in project files ---
Write-Host "`n[*] Scanning project files under $SearchPath ..."
$projs = Get-ChildItem -Path $SearchPath -Recurse -Include '*.csproj','*.fsproj','*.vbproj' -ErrorAction SilentlyContinue
foreach ($p in $projs) {
  try {
    [xml]$xml = Get-Content $p.FullName -ErrorAction Stop
    foreach ($ref in $xml.SelectNodes('//PackageReference')) {
      $name = $ref.GetAttribute('Include')
      $ver  = $ref.GetAttribute('Version')
      if ($VulnPkgs -contains $name -and $ver) {
        $found = $true
        $clean = $ver -replace '-.*',''
        if ($ver -match '^10\.' -and [version]$clean -lt $SafeVer10) {
          Write-Host "[!] VULNERABLE: $($p.FullName) -> $name $ver" -ForegroundColor Red
          $vuln = $true
        } elseif ($ver -match '^11\.0\.0-(preview|rc\.[12])') {
          Write-Host "[!] VULNERABLE: $($p.FullName) -> $name $ver" -ForegroundColor Red
          $vuln = $true
        } else {
          Write-Host "[+] OK: $($p.FullName) -> $name $ver" -ForegroundColor Green
        }
      }
    }
  } catch {}
}

# --- Verdict ---
Write-Host ''
if (-not $found) {
  Write-Host 'UNKNOWN - No .NET 10/11 SDK or Blazor WASM package references found' -ForegroundColor Yellow
  exit 2
} elseif ($vuln) {
  Write-Host 'VULNERABLE - CVE-2026-102870: Update SDK to 10.0.14+ and NuGet packages' -ForegroundColor Red
  exit 1
} else {
  Write-Host 'PATCHED - No vulnerable Blazor WASM debug proxy versions detected' -ForegroundColor Green
  exit 0
}