← Back to Feed CACHED · 2026-06-25 07:15:21 · CACHE_KEY CVE-2020-0646
CVE-2020-0646 · CWE-20 · Disclosed 2022-05-24

A remote code execution vulnerability exists when the Microsoft

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

A SharePoint user smuggles a compiler directive inside a workflow definition and the server obediently builds it into native code

CVE-2020-0646 is an input-validation flaw in the Microsoft .NET Framework Workflow Compiler as invoked by SharePoint when processing XOML (Extensible Object Markup Language) workflow definitions. An authenticated SharePoint user with rights to create or edit a workflow can inject crafted XML that the server-side compiler treats as code, yielding RCE as the SharePoint application pool identity (typically the farm or web-app service account). Affected: .NET Framework 3.5 / 4.5.2 / 4.6 / 4.6.2 / 4.7 / 4.7.1 / 4.7.2 / 4.8 across Windows client and Server SKUs, and SharePoint Server 2010 SP2 / 2013 SP1 / 2016 / 2019 prior to the January 2020 cumulative update.

Vendor labels this 9.8 / Critical with PR:N, which is misleading: MSRC's own write-up and MDSec's PoC require an authenticated SharePoint principal that can submit a workflow. Reality is closer to AV:N / PR:L / UI:N / RCE — i.e., a high authenticated bug, not a drive-by. That said, EPSS 0.992, KEV listing, public Metasploit module, and the canonical SharePoint role (identity-adjacent, frequently service-account-rich) keep this firmly in HIGH territory.

"KEV-listed SharePoint XOML RCE — requires an authenticated low-priv SharePoint user, but the chain ends in w3wp.exe code execution on the farm."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Acquire a SharePoint foothold account

The attacker authenticates to the target SharePoint farm with any account that has *Add and Customize Pages* or workflow-author rights on at least one site. Credentials are typically harvested via phishing, password spray, or leaked dumps, since SharePoint is commonly exposed to SSO with the corporate IdP.
Conditions required:
  • Reachable SharePoint web front-end (intranet or via VPN/ZTNA)
  • Valid AD/Entra credentials with site-level workflow permissions
Where this breaks in practice:
  • MFA on the IdP blocks most credential-stuffing
  • ZTNA/conditional access removes most public exposure
  • Many farms restrict workflow-author role to a small group
Detection/coverage: Sign-in anomaly detection in Entra ID Protection / Okta ThreatInsight.
STEP 02

Craft malicious XOML workflow

Using the technique published by MDSec (Soroush Dalili) and weaponized in Metasploit module exploit/windows/http/sharepoint_workflows_xoml, the attacker builds a XOML payload that injects <x:Code> (or equivalent compiler directive) into the workflow XML. SharePoint passes this to the Workflow Compiler, which fails to strip code blocks before invoking csc.exe.
Conditions required:
  • Knowledge of target site URL and a writable workflow list
Where this breaks in practice:
  • WAF rules with XOML/<x:Code> signatures can block the upload
  • SharePoint hardening that disables sandboxed/declarative workflows
Detection/coverage: Defender for Endpoint and Sysmon catch anomalous csc.exe invocations parented to w3wp.exe.
STEP 03

Submit workflow and trigger compilation

The attacker POSTs the XOML to the workflow endpoint (/_vti_bin/... or /_layouts/15/WrkStat.aspx-adjacent handlers). The Workflow Compiler runs server-side, compiles the embedded C# into an assembly, and loads it in the SharePoint worker process, executing arbitrary code as the app pool identity.
Conditions required:
  • Server has not received the January 2020 .NET / SharePoint CU
Where this breaks in practice:
  • Patched farms reject the embedded <Code> element outright
  • Restricted IIS app-pool identities limit lateral movement
Detection/coverage: IIS logs show POST to workflow handler immediately followed by csc.exe; high-signal alert.
STEP 04

Pivot from app pool to farm and AD

The SharePoint farm account is typically a domain user with read access to the configuration DB and, in poorly scoped deployments, local admin on every WFE. The attacker dumps the config DB to recover other service accounts, harvests Kerberos tickets via Rubeus, and pivots toward AD via Kerberoasting or constrained-delegation abuse.
Conditions required:
  • Service account is over-privileged or has SPN-based delegation
Where this breaks in practice:
  • Properly scoped gMSA/MSA service accounts with no logon-as-batch rights elsewhere
  • Tiered admin model
Detection/coverage: Defender for Identity surfaces Kerberoasting and unusual LDAP enumeration from a SharePoint WFE.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusKEV-listed by CISA; observed in opportunistic SharePoint compromise campaigns since 2020. Pairs frequently with CVE-2019-0604 in the same intrusion sets.
Public PoCDetailed write-up + PoC by Soroush Dalili (MDSec, Jan 2020); Metasploit module exploit/windows/http/sharepoint_workflows_xoml (rapid7/metasploit-framework PR #13122 by zeroSteiner).
EPSS0.99193 — top ~0.5 percentile; among the most-exploited CVEs tracked by FIRST.
CISA KEVListed; remediation required for federal agencies under BOD 22-01.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8 Critical. Real-world PR is L (workflow author), not N — adjusted score closer to 8.5.
Affected versions.NET Framework 3.5, 4.5.2, 4.6, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8 on Windows 7/8.1/10/Server 2008–2019; SharePoint 2010 SP2, 2013 SP1, 2016, 2019 pre-Jan 2020 CU.
Fixed inMicrosoft January 2020 Patch Tuesday (KB4534271 / KB4534976 / KB4535102 family for .NET; KB4484149 / KB4484142 / KB4484113 for SharePoint).
Exposure (Shodan/Censys)~250k SharePoint instances reachable on the public internet per Shodan; majority sit behind SSO/Entra, but legacy on-prem SharePoint 2013/2016 farms remain heavily represented.
DisclosureCoordinated disclosure 14 Jan 2020 (Microsoft Patch Tuesday). NVD record updated 2022-05-24.
ReporterSoroush Dalili (@irsdl), MDSec ActiveBreach.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (8.5/10)

The decisive factor is the authenticated-user prerequisite — the chain requires a SharePoint principal with workflow-author rights, not an unauthenticated internet attacker, which is why this lands at HIGH rather than CRITICAL despite the 9.8 vendor score. The role multiplier prevents any further downgrade: SharePoint farms run with domain-joined, frequently over-privileged service accounts, so the blast radius from a single RCE routinely extends into AD.

HIGH exploitability and PoC maturity
HIGH KEV / EPSS signal
MEDIUM real-world exposure population (most farms are internal-only)

Why this verdict

  • Authentication required, not PR:N: MDSec's PoC and the Metasploit module both need a workflow-author principal. The CVSS PR:N claim does not survive contact with the source research — this is the single biggest reason for the downgrade from 9.8.
  • KEV + EPSS 0.992: active, repeatable exploitation in the wild; ignoring this entirely is not defensible even with the auth prerequisite.
  • Role multiplier — SharePoint as identity-adjacent tier: SharePoint farm accounts are domain users, often with read access to AD attributes, mailbox enumeration via Graph, and SPNs that invite Kerberoasting. RCE in w3wp.exe is a credible launchpad to domain compromise, which floors this at HIGH.
  • Compensating friction: most modern farms front SharePoint with Entra SSO + MFA + Conditional Access; the attacker must first land a valid corporate identity, which is non-trivial but not rare.
  • Patch is six years old: any unpatched farm is by definition outside normal lifecycle and likely has additional 2019-era SharePoint bugs (CVE-2019-0604) co-resident.

Why not higher?

CRITICAL would require unauthenticated reachable RCE on a widely-exposed component. The auth requirement collapses the candidate population to existing employees / contractors / partners with workflow rights, and most SharePoint farms are not internet-facing in 2026.

Why not lower?

MEDIUM is wrong because KEV listing and EPSS 0.992 reflect ongoing real-world abuse, and the role multiplier (SharePoint farm service account → AD) means a successful chain is not contained to a single host.

05 · Compensating Control

What to do — in priority order.

  1. Apply January 2020 (or later) SharePoint + .NET cumulative updates — This is the only durable fix. Under the noisgate remediation SLA for HIGH, complete farm-wide patching within 180 days; if any farm is internet-reachable, treat as KEV override and patch within hours.
  2. Block declarative/sandboxed workflow creation for non-admin users — In Central Admin → Web Application General Settings, disable user-defined workflows on web apps that don't need them. Removes the primary attack surface even on unpatched farms. Deploy within 30 days per noisgate mitigation SLA for HIGH.
  3. Put SharePoint behind Entra Application Proxy / ZTNA with MFA + device compliance — Eliminates anonymous internet exposure and raises the cost of acquiring the workflow-author foothold. Conditional-access policies should require compliant device for any non-read action.
  4. Constrain SharePoint farm and app-pool service accounts — Convert to gMSA, strip local admin on non-WFE hosts, remove SPN-based unconstrained/constrained delegation, and add to Protected Users where compatible. Limits blast radius post-RCE.
  5. Deploy WAF rules blocking <x:Code> / Code= in XOML POSTs — F5 ASM, Azure WAF, and Imperva all have rules for this CVE family — enable in blocking (not detect-only) mode.
What doesn't work
  • Disabling anonymous access alone — exploitation is authenticated; anonymous lockdown doesn't help.
  • EDR on the WFE without baselining csc.exe parented by w3wp.execsc.exe is occasionally legitimate during ASP.NET runtime compilation; you need a specific detection, not generic process-tree alerts.
  • Network IDS signatures looking for .xoml extensions — payload is delivered via SOAP/REST endpoints, not as a file upload with that extension.
06 · Verification

Crowdsourced verification payload.

Run on each SharePoint WFE / app server as a local admin (or via PSRemoting from an auditor workstation: Invoke-Command -ComputerName SP01 -ScriptBlock { ... }). Script inspects installed .NET Framework build and SharePoint CU level against the January 2020 fix baseline. Outputs VULNERABLE, PATCHED, or UNKNOWN.

noisgate-verify.ps1
POWERSHELLREAD-ONLYSAFE
#requires -RunAsAdministrator
# noisgate verification: CVE-2020-0646 (.NET Framework / SharePoint XOML RCE)
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

$ErrorActionPreference = 'Stop'
$verdict = 'UNKNOWN'

try {
    # --- .NET Framework 4.x build check (fix shipped Jan 14 2020) ---
    $ndp = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' -ErrorAction SilentlyContinue
    $release = $ndp.Release
    # Jan-2020 servicing baselines: 4.8=528372+, 4.7.2=461823+, 4.7.1=461320+, 4.6.2=394821+
    $netVulnerable = $false
    if ($release) {
        if     ($release -ge 528040 -and $release -lt 528372) { $netVulnerable = $true }
        elseif ($release -ge 461808 -and $release -lt 461823) { $netVulnerable = $true }
        elseif ($release -ge 461308 -and $release -lt 461320) { $netVulnerable = $true }
        elseif ($release -ge 394802 -and $release -lt 394821) { $netVulnerable = $true }
    }

    # --- SharePoint version check (if installed) ---
    $spVulnerable = $false
    $spReg = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\*\WSS' -ErrorAction SilentlyContinue
    foreach ($sp in $spReg) {
        $v = [version]$sp.Version
        # SP2019 fix: 16.0.10362.20001 | SP2016: 16.0.4915.1000 | SP2013: 15.0.5197.1000
        if ($v.Major -eq 16 -and $v.Minor -eq 0 -and $v.Build -lt 4915) { $spVulnerable = $true }
        if ($v.Major -eq 15 -and $v.Minor -eq 0 -and $v.Build -lt 5197) { $spVulnerable = $true }
    }

    if ($netVulnerable -or $spVulnerable) { $verdict = 'VULNERABLE' }
    elseif ($release) { $verdict = 'PATCHED' }
}
catch {
    $verdict = 'UNKNOWN'
}

Write-Output $verdict
switch ($verdict) {
    'PATCHED'    { exit 0 }
    'VULNERABLE' { exit 1 }
    default      { exit 2 }
}
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: enumerate every on-prem SharePoint farm (2013/2016/2019) and every Windows host with .NET Framework 3.5–4.8 that hasn't received the January 2020 (or newer) cumulative update — these are six years overdue. Because this CVE is KEV-listed with EPSS 0.992, the KEV override applies and you should treat mitigation as within hours, not the 30-day noisgate mitigation SLA for HIGH: disable user-defined workflows on every reachable farm and block <x:Code> payloads at the WAF today. Full vendor patching (the noisgate remediation SLA for HIGH = ≤180 days) should be compressed to the next change window — there is no excuse for a six-year-old patch gap on a SharePoint farm. Any internet-exposed SharePoint instance is an incident-response engagement, not a vulnerability-management ticket.

Sources

  1. NVD — CVE-2020-0646
  2. MDSec — Code injection in Workflows leading to SharePoint RCE
  3. Metasploit PR #13122 — SharePoint Workflows XOML RCE
  4. AttackerKB — CVE-2020-0646
  5. CISA KEV Catalog
  6. GHSA-4w3v-83v8-mg94
  7. Tenable — CVE-2020-0646
  8. MSRC advisory
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.