ToolShell: Unauthenticated RCE in SharePoint via XML Deserialization
Jan 28, 2026·5 min read·1 visit
Executive Summary (TL;DR)
Unauthenticated attackers can chain an authentication bypass in `ToolPane.aspx` with a deserialization flaw in `DataSet` processing to gain Remote Code Execution (RCE) on SharePoint servers. The flaw exploits the `msdata:DataType` XML attribute to instantiate dangerous .NET gadgets.
A Critical Remote Code Execution vulnerability in Microsoft SharePoint Server, dubbed 'ToolShell', allows attackers to execute arbitrary code via unsafe XML deserialization of DataSet objects. When chained with an authentication bypass (CVE-2025-49706), it permits unauthenticated attackers to compromise on-premises SharePoint farms fully.
The Hook: Another Day, Another SharePoint RCE
SharePoint is the enterprise gift that keeps on giving. Just when you thought Microsoft had finally nailed the coffin shut on deserialization bugs, Pwn2Own Berlin 2025 comes along and reminds us that legacy code never dies—it just waits for a new researcher to poke it with a stick.
Enter CVE-2025-49704, affectionately nicknamed "ToolShell". Discovered by the sharp minds at Viettel Cyber Security, this isn't your average script-kiddie SQL injection. This is a masterclass in .NET internals abuse, specifically targeting the DataSet class—a component so notoriously fragile that security researchers look at it the way a hungry wolf looks at a limp sheep.
But the real kicker? On its own, this is an authenticated vulnerability. You need credentials. But because SharePoint is a massive, sprawling beast of spaghetti code, it was immediately chained with CVE-2025-49706, a ludicrously simple authentication bypass in the ToolPane component. The result? Unauthenticated Remote Code Execution as the SharePoint service account. If you're running SharePoint on-prem and haven't patched since July 2025, you might as well hand the keys to the nearest ransomware operator.
The Flaw: The 'VIP Pass' of XML Parsing
To understand this vulnerability, you have to understand System.Data.DataSet. In the .NET world, DataSet is a complex object that can hold tables, relationships, and constraints. It can also serialize and deserialize itself to and from XML. For years, Microsoft has been playing whack-a-mole with DataSet deserialization gadgets, adding type filters and allow-lists to prevent attackers from instantiating dangerous objects.
Here is where the logic failed. The DataSet XML parser respects an attribute called msdata:DataType. Think of this attribute as a VIP badge. Normally, the parser checks the type against a list of safe types. However, when the XML schema explicitly defines a column's type using msdata:DataType, the parser essentially says, "Oh, the schema says this is a System.Collections.Generic.List, so I'll trust it and instantiate it."
This behavior allows an attacker to bypass the type restrictions. Instead of just loading integers or strings, the attacker tells the parser to load a highly specific, nested generic type: System.Collections.Generic.List containing a System.Data.Services.Internal.ExpandedWrapper. Why this wrapper? Because it's the perfect Trojan Horse to smuggle in the actual gadgets: LosFormatter and ObjectDataProvider.
The Smoking Gun: Anatomy of the Payload
The exploit doesn't require compiling C#; it requires crafting the perfect XML lie. The attacker submits a "Dashboard Web Part" (DWP) file, which SharePoint parses. Embedded within this is an XML schema that defines the trap.
Take a look at this snippet of the malicious schema. This is where the magic happens:
<xs:element name="ColumnName"
msdata:DataType="System.Collections.Generic.List`1[[System.Data.Services.Internal.ExpandedWrapper`2[[System.Web.UI.LosFormatter, System.Web, ...],[System.Windows.Data.ObjectDataProvider, PresentationFramework, ...]], ...]]"
type="xs:anyType" minOccurs="0"/>See that msdata:DataType? It is instructing the deserializer to create a List of ExpandedWrapper objects. Inside that wrapper, we have two critical components:
LosFormatter: A class designed to serialize/deserialize Web Forms view state. It has a methodDeserialize(string)that is incredibly dangerous if passed untrusted data.ObjectDataProvider: A WPF gadget that allows you to invoke methods on objects.
The attacker configures the ObjectDataProvider to call LosFormatter.Deserialize() on a Base64 string provided in the payload. That Base64 string contains another serialized payload (the "gadget chain"), usually generated by a tool like YSoSerial.Net, which finally executes cmd.exe or PowerShell.
The Exploit: Chaining the bypass
A locked door is useless if you leave the window open. CVE-2025-49704 requires authentication. But who needs a password when you have CVE-2025-49706?
The authentication bypass is almost insulting in its simplicity. The ToolPane.aspx page checks if you are allowed to edit the page. The check logic had a flaw where if the request contained a specific Referer header (pointing to SignOut.aspx) and the query string DisplayMode=Edit, SharePoint's logic short-circuited and allowed the request to proceed without a valid session.
The Attack Chain:
- Knock on the Door: The attacker sends a POST request to
/_layouts/15/ToolPane.aspx. - The Lie: They set
Referer: https://target/SignOut.aspxandDisplayMode=Edit. - The Payload: In the POST body, they send the malicious XML via the
MSOTlPn_DWPparameter. - Execution: SharePoint accepts the request, parses the DWP, hits the
msdata:DataTypetrap, deserializes theLosFormatter, and boom—you have a shell running asNT AUTHORITY\NETWORK SERVICE(or worse).
The Impact: From Zero to System
This is a full system compromise. SharePoint runs with significant privileges and often has access to the domain controller, SQL servers, and vast troves of sensitive corporate data.
We have already seen this used in the wild by the Warlock ransomware group. They didn't just steal data; they encrypted entire farms. Because SharePoint is often the central repository for an organization's knowledge, losing it is catastrophic.
Furthermore, because the exploit leaves very few traces on disk (it's mostly in-memory deserialization), forensic analysis can be difficult without robust logging. You aren't looking for a dropped binary; you are looking for a malicious XML string in your IIS logs.
The Fix: Patch and Pray
Microsoft released patches in July 2025 (KB5002618 for SP2019, KB5002617 for SP2016). The patch effectively kills the msdata:DataType bypass by enforcing stricter type checking even when that attribute is present.
Crucial Note: If you are a SharePoint admin, you know the drill, but I'll say it anyway: Installing the MSP file is not enough. You absolutely must run the SharePoint Products Configuration Wizard (psconfig.exe) after installation. If you don't, the database schemas and internal logic won't actually update, and you might still be vulnerable—or worse, your farm will just crash.
If you cannot patch immediately, you can block access to /_layouts/15/ToolPane.aspx at your WAF. Honestly, nobody should be accessing the ToolPane from the public internet anyway.
Official Patches
Technical Appendix
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HAffected Systems
Affected Versions Detail
| Product | Affected Versions | Fixed Version |
|---|---|---|
SharePoint Server 2019 Microsoft | < 16.0.10417.20027 | 16.0.10417.20027 |
SharePoint Enterprise Server 2016 Microsoft | < 16.0.5508.1000 | 16.0.5508.1000 |
| Attribute | Detail |
|---|---|
| Vulnerability Type | Unsafe Deserialization |
| Attack Vector | Network (HTTP POST) |
| Auth Required | None (when chained with CVE-2025-49706) |
| CVSS v3.1 | 8.8 (High) |
| Payload | XML with msdata:DataType attribute |
| KEV Status | Listed (Active Exploitation) |
| Exploit Capability | Remote Code Execution (System/Service Account) |
MITRE ATT&CK Mapping
Known Exploits & Detection
Vulnerability Timeline
Subscribe to updates
Get the latest CVE analysis reports delivered to your inbox.