MOVEit Transfer CVE-2023-34362 & CVE-2023-35036: from SQL injection to .NET deserialization RCE
The MOVEit Transfer bug that drove one of 2023's largest breach waves, taken apart end to end: an unauthenticated stacked SQL injection, privilege escalation by inserting an admin, an IP-whitelist bypass, and finally unsafe .NET deserialization for code execution. Plus the second injection, CVE-2023-35036.
MOVEit Transfer is a managed file-transfer server: SFTP, FTPS, HTTPS and AS2, with access controls and encryption on top. In mid-2023 it became the epicenter of one of the year's largest breach waves. CVE-2023-34362 (CVSS 9.8) is the reason. This is a full walkthrough of the chain, followed by the second SQL injection, CVE-2023-35036 (CVSS 9.1), that shipped in the same family.

The shape of the chain
CVE-2023-34362 is not a single bug, it is a chain of four steps, each covering the gap left by the last:
- 01Unauthenticated SQL injection in the file-transfer web interface.
- 02Privilege escalation by inserting an attacker-controlled admin account.
- 03An IP-whitelist bypass to reach an internal-only endpoint.
- 04Unsafe .NET deserialization to turn database control into code execution.

Step 1: the SQL injection
The injection lives in the UserGetUsersWithEmailAddress method inside UserEngine.cs. Reaching it does not require a session in the normal sense: the exploit manipulates MOVEit's session variables through request headers and drives the injectable code path via the guestaccess.aspx endpoint. Because the injection is stacked (multiple statements per query), the attacker is not limited to reading data — they can execute arbitrary INSERT/UPDATE statements against the backing database.
Step 2: escalate by inserting an admin
With write access to the database, the attacker inserts a new administrator account directly into the users table. MOVEit trusts its own tables for identity, so a row is an account. From there they hold admin privileges without ever knowing a password.
Step 3: bypass the IP whitelist
The deserialization sink lives behind machine2.aspx, an endpoint intended to be reachable only from trusted, whitelisted hosts. Two problems combine to defeat that control:
- The IP allow-list itself is stored in the
hostpermitstable, which the stacked injection can write to. Insert the attacker's address and you are "trusted". - Request processing by the ISAPI extension (
moveitsapi.dll) can be bypassed by embedding the header values it expects inside Cookie fields, enabling an SSRF-style reach intomachine2.aspx.
Either way, the internal-only endpoint is now in reach.
Step 4: unsafe .NET deserialization
The endpoint's DeserializeFileUploadStream method deserializes untrusted .NET objects read from the State column of an upload record. The exploit uses a two-stage upload: an initial partial upload stores the serialized payload in that column, and completing the upload triggers deserialization of it. A crafted gadget in the payload turns that deserialize into remote code execution.
Chain the four steps and the result is unauthenticated RCE on the MOVEit server — which, given what MOVEit is used for, means direct access to exactly the sensitive files organizations deployed it to protect.
CVE-2023-35036: the second injection
Progress's follow-up review surfaced a second SQL injection, patched as CVE-2023-35036. This one is in the FolderIDToPath method, which concatenates user-controlled input straight into a query. The CleanForSQL sanitizer only strips ', " and ;, so it misses backslash escape sequences entirely. The injectable input arrives through the X-siLock-FolderID and X-siLock-RelativePath headers.
There is a second vector too: SILCertToUser.cs interpolates the Common Name (CN) field of a client certificate directly into a query — though that path additionally requires already-trusted-IP status, which step 3 above happens to provide.
Mitigation
- Patch MOVEit Transfer to a fixed release for both CVE-2023-34362 and CVE-2023-35036, and follow Progress's advisories.
- Assume compromise if you ran a vulnerable version while it was exposed: hunt for unexpected admin accounts, rows added to
hostpermits, and web shells or unfamiliar files dropped by the deserialization step. - Restrict network exposure of the web interface; a managed file-transfer server rarely needs to be open to the whole internet.
- The durable fixes are architectural: parameterized queries everywhere, no deserialization of untrusted
State, and identity that does not live in a table a single injection can write to.
References & further reading
Dau Hoang Tai
Co-Founder, Starfish Security