flawopen.com/Incidents/MOVEit CVE-2023-34362
A courier company runs a secure depot where other businesses leave parcels for each other. Someone finds that the request form at the front desk can be filled in with extra instructions that the clerk follows literally — including "and also give me a permanent staff pass". Because hundreds of businesses all use the same depot, robbing the depot once robs all of them.
On 31 May 2023 Progress Software disclosed a critical vulnerability in MOVEit Transfer, its managed file transfer product, which was already being exploited in the wild. CVE-2023-34362 is an SQL injection in the web application reachable without authentication, allowing an attacker to read and manipulate the backing database and, in practice, to achieve code execution on the server.
The Cl0p ransomware group had been exploiting it ahead of disclosure. Rather than encrypting systems, they used it to plant a web shell — publicly tracked as LEMURLOOT — and steal the files held in each MOVEit instance. Because MFT servers hold data belonging to an organisation's customers, partners and payroll providers, the breach cascaded outward: a single compromised MOVEit deployment at a service provider exposed data for every downstream client it served. The eventual victim count ran into the thousands of organisations and tens of millions of individuals.
The flaw was straightforward: user-controlled values reached SQL statements in the MOVEit web application without being properly separated from the query text. Progress described the issue as an SQL injection permitting unauthenticated access to the database; exploitation varied slightly by backend engine — MySQL, Microsoft SQL Server or Azure SQL — because what an attacker could do after gaining query control depended on the engine's capabilities.
Query control in an application's own database is rarely the end state an attacker wants. Here it allowed manipulation of the application's session and account records — enabling the attacker to forge an authenticated context and then use the product's legitimate file-handling functionality to write a web shell to disk. The database was the pivot, not the prize.
The fact that three separate SQL injection vulnerabilities were found in the same product within weeks is itself the significant finding. That pattern points to a systemic practice — string-built queries used broadly across a codebase — rather than a single careless line.
// Query text and data concatenated. // The database cannot tell which // part the developer intended. string sql = "SELECT * FROM folders WHERE id = '" + Request["folderId"] + "'"; cmd = new SqlCommand(sql, conn);
// Data travels separately from the // query text. No parsing ambiguity // is possible. string sql = "SELECT * FROM folders WHERE id = @id"; cmd = new SqlCommand(sql, conn); cmd.Parameters.AddWithValue( "@id", Request["folderId"]);
Largely, when used normally — ORMs bind parameters by default. The risk returns when developers drop to raw SQL fragments or string-build a query builder's conditions, which most ORMs permit.
Signature-based filtering catches unsophisticated payloads and can slow mass scanning, but it is routinely bypassed and was not a reliable defence here. It is a mitigation layer, not a substitute for parameterised queries.