An attacker with nothing more than a Site Member account - the permission level you hand to contractors, interns, and every employee who needs to upload a document - can run arbitrary code on your on-premises SharePoint server. Microsoft shipped the fix for CVE-2026-45659 as an out-of-band update on May 21, 2026. On July 1, CISA added it to the Known Exploited Vulnerabilities catalog with a federal remediation deadline of July 4. If you run SharePoint on your own hardware, the window to patch quietly has closed.
The bug is a deserialization of untrusted data flaw (CWE-502), CVSS 8.8, affecting SharePoint Server Subscription Edition, SharePoint Server 2019, and SharePoint Enterprise Server 2016. Microsoft rated it "Exploitation Less Likely" at release. Six weeks later CISA confirmed it is being used in the wild. That gap between a vendor's severity guess and what attackers actually do is exactly why this one earned a KEV entry before most teams had it on their radar.
Who this affects, and who can close the tab
This is an on-premises problem. SharePoint Online and the SharePoint that ships inside Microsoft 365 are not affected, because Microsoft patches the hosted service centrally. If your entire SharePoint footprint lives in M365, this one is not yours - go spend the time on something that is. Everyone still running Subscription Edition, 2019, or 2016 on their own servers is in scope, and that population is larger than the "everybody moved to the cloud" story suggests. Manufacturers, law firms, healthcare practices, and government contractors routinely keep on-prem SharePoint for document management they will not or cannot migrate.
The authentication requirement reads like a mitigation and is not one. Site Member is close to the lowest useful permission on a SharePoint site: any phished employee credential, any leftover contractor account, any loose self-registration flow puts an attacker at that level. Read "authenticated" as "trivially reachable," not "hard to reach." For a small business, the practical stakes are simple: the compromised box is the file server holding your contracts, HR records, and internal wikis, and it runs with enough standing on the network to become the jump point into the rest of the domain.
How a low-privilege account turns into code execution
The mechanism is worth understanding, because it explains why the fix has two parts. SharePoint accepts a serialized .NET object inside a request that a Site Member is allowed to reach, and the vulnerable code path deserializes that object without restricting the types it will rebuild. An attacker crafts a gadget chain - a sequence of legitimate .NET classes whose constructors and property setters, invoked during deserialization, end in a call that runs a command. The command runs in the context of the IIS worker process, w3wp.exe, under the application-pool identity. That identity is usually a domain service account with rights across the farm, which is why a single content-contributor login becomes code execution on the server and, from there, a foothold on the network.
Once code is running, the first two things an operator does are predictable: write a small web shell somewhere IIS will serve it, and read the ASP.NET secrets out of web.config. The second step is the one that turns a patchable bug into a persistent problem, and it is where the 2025 campaign wrote the playbook everyone else is now copying.
The ToolShell lesson: the patch is step one, not the finish line
In July 2025, the on-prem SharePoint mass-exploitation campaign known as ToolShell (CVE-2025-53770 and CVE-2025-53771) hit more than 400 organizations in days. The operators did more than run code. They stole each server's ASP.NET machineKey material - the ValidationKey and DecryptionKey out of web.config - and used it to forge valid __VIEWSTATE payloads. A forged view state lets an attacker walk back in through the front door as a trusted request, authenticated by keys they now hold, even after the patch is installed. Microsoft made machine-key rotation a required remediation step in its July 22, 2025 guidance, not an optional cleanup.
CVE-2026-45659 is the same class of bug in the same product. Assume the same tradecraft. If your server was reachable and unpatched at any point since late June, installing the update now does nothing about keys an attacker may already be holding. This is the part almost every "patch this" writeup skips, and it is the part that decides whether you actually evicted the intruder or just annoyed them.
Patch, then rotate the keys twice
The order of operations
- Install the update on every farm server. For Subscription Edition the fixed build is
16.0.19725.20280or later; 2019 and 2016 have their own KB packages. CVE-2026-45659 was inadvertently left out of the initial May 2026 bulletin and added out of band, so verify the build number rather than trusting a patch name - if you already applied the May cumulative updates, confirm the build and you are covered. - Rotate the machine keys, before and after patching per Microsoft's guidance, then restart IIS so the services drop the old keys from memory.
- Confirm propagation. New ValidationKey and DecryptionKey values should appear in
web.configacross the farm.
# Run in the SharePoint Management Shell on a farm server.
# Rotate the farm machine key (repeat this step after the patch is in).
Update-SPMachineKey -WebApplication https://sharepoint.contoso.com
# Force every server to reload web.config and purge the old key from memory.
# iisreset is the step that actually invalidates a stolen key - do not skip it.
Get-SPServer | Where-Object { $_.Role -ne 'Invalid' } |
ForEach-Object { Write-Host "Reset IIS on $($_.Address)"; iisreset.exe $_.Address /noforce }
If you manage keys through the Central Administration timer job, run that job instead of the cmdlet, but the two-rotation-plus-iisreset sequence is the same. The single most common mistake here is patching, rotating once, and never restarting IIS - the old key stays live in the worker process and the forged view state keeps working.
Hunt for the web shell you may already have
Deserialization RCE in SharePoint almost always lands as a web shell written into the LAYOUTS directory and executed by the IIS worker process, w3wp.exe. During ToolShell the dropped file was spinstall0.aspx; treat any unexplained .aspx as the current one. Two hunts you can run on each server today:
# 1. Recently written script files under the SharePoint LAYOUTS path
# (hive 16 = SharePoint 2016/2019/Subscription Edition).
$layouts = "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\TEMPLATE\LAYOUTS"
Get-ChildItem $layouts -Recurse -Include *.aspx,*.ashx,*.asmx -ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-30) } |
Select-Object FullName, LastWriteTime, Length | Sort-Object LastWriteTime -Descending
# 2. IIS worker process spawning a shell - the classic post-exploitation tell (Sysmon Event ID 1).
Get-WinEvent -FilterHashtable @{ LogName='Microsoft-Windows-Sysmon/Operational'; Id=1 } -MaxEvents 5000 |
Where-Object { $_.Message -match 'ParentImage:.*w3wp\.exe' -and
$_.Message -match '\\(cmd|powershell|cscript|wscript)\.exe' } |
Select-Object TimeCreated, Message
If your servers report into Microsoft Defender for Endpoint or you forward device telemetry to Sentinel, the same behavioral signal is one KQL query away and does not depend on having deployed Sysmon:
// Defender for Endpoint / Sentinel: IIS worker process spawning a command shell.
DeviceProcessEvents
| where InitiatingProcessFileName =~ "w3wp.exe"
| where FileName in~ ("cmd.exe","powershell.exe","powershell_ise.exe",
"cscript.exe","wscript.exe","mshta.exe")
| where Timestamp > ago(30d)
| project Timestamp, DeviceName, InitiatingProcessCommandLine, FileName, ProcessCommandLine
| sort by Timestamp desc
No Sysmon and no EDR on the box? Pivot to the IIS logs under %SystemDrive%\inetpub\logs\LogFiles and look for POST requests to /_layouts/15/ pages you do not recognize, then read the SharePoint ULS logs for deserialization exceptions around the same timestamps. One randomly named .aspx you cannot account for is enough to open an incident and pull the server for forensics rather than trusting it.
Do not assume you would already know if you ran on-prem SharePoint. On engagements we regularly find a forgotten 2016 or 2019 farm a prior admin stood up for one department and never decommissioned. A quick way to scope your own estate: from an internal host, fingerprint the servers you think are SharePoint and confirm the version, then reconcile that against what your patch tooling actually covers.
# Fingerprint suspected SharePoint hosts from an internal scanning box.
# The MicrosoftSharePointTeamServices response header leaks the build number.
for h in $(cat sharepoint_hosts.txt); do
echo -n "$h -> "
curl -skI "https://$h/_layouts/15/start.aspx" \
| grep -i "MicrosoftSharePointTeamServices" || echo "no SP header"
done
If you genuinely cannot patch this week
- Get the server off the public internet. On-prem SharePoint should sit behind the VPN or an authenticating reverse proxy, never published directly for remote document access. Most small-business SharePoint compromises begin because the box was internet-facing for convenience.
- Turn on AMSI in Full Mode for SharePoint and confirm Microsoft Defender (or your AV) is actually running on the server. Microsoft added AMSI integration to SharePoint specifically to blunt this exploit class; it buys detection, not immunity.
- Watch authentication. A burst of new low-privilege accounts, or sign-ins from unusual locations immediately preceding a spike in SharePoint traffic, is your early warning that someone is lining up the Site Member access this bug needs.
Assume the machine keys are already stolen
If you run on-prem SharePoint, the sequence this week is fixed: patch every server, rotate the machine keys twice, restart IIS everywhere, then hunt the LAYOUTS directory and the IIS logs before you call the environment clean. The KEV deadline is July 4 and the exploitation is happening now, so treat the calendar as real. Carry the broader lesson forward too - for any deserialization flaw in an ASP.NET application that stores secret keys, the update closes the door but a stolen key is a copy that outlives the fix. Verify eviction; do not assume it.
Want a second set of eyes on a SharePoint server you think is patched?
We help teams work out whether an actively-exploited flaw was used against them before the fix landed - the web-shell hunt, the machine-key rotation, and the containment if something is already inside. Book a session and we will walk your on-prem footprint with you.
