The MOVEit breach explained: how one SQL injection exposed so many organisations
In 2023 attackers used a SQL injection flaw in MOVEit Transfer to steal data from huge numbers of organisations. What it is and how to prevent it.
By the Dignite Studios team · Nov 5, 2026 · 7 min read
SQL injection is almost older than some of the people now being asked to defend against it. It was described publicly in the late 1990s. And yet, in the spring of 2023, it was the way into one of the largest data thefts of the year.
What happened
MOVEit Transfer is software that organisations use to send and receive sensitive files: payroll data, medical records, financial documents. Around the end of May 2023, attackers began exploiting a previously unknown SQL injection flaw in its web application, later tracked as CVE-2023-34362.
The vendor, Progress Software, disclosed the problem on 31 May. The attackers, a ransomware group known as Cl0p, were not locking anyone's systems. They quietly took the files stored in the product, then went to each victim and demanded payment to keep the data off the internet. Further related flaws were discovered afterwards as the product was examined more closely.
Because so many organisations used the same product, the damage spread widely. Early reports spoke of hundreds of organisations, and later tallies counted far more, along with tens of millions of individuals whose information was involved. Many of those people had never heard of MOVEit. Their data was held by a company that used it, or by the supplier of that company.
SQL injection, explained properly
Most web apps talk to a database, and they do it by building a command from pieces. Part of the command is fixed, and part comes from whatever the visitor typed. The trouble starts when the typed part isn't kept separate. Here's the risky version in PHP:
// Risky: whatever the visitor types becomes part of the command
$sql = "SELECT * FROM orders WHERE email = '" . $_GET['email'] . "'";If someone types a normal email address, it works. If they type something like ' OR '1'='1, they've changed the meaning of the command, and now it returns every order instead of one. With a little more effort, an attacker can read other tables, change records or, in the worst cases, take over the server.
The fix is called a parameterised query. You send the command and the values separately, so the database always treats the value as data and never as instructions:
// Safer: the value travels separately from the command
$stmt = $pdo->prepare('SELECT * FROM orders WHERE email = :email');
$stmt->execute(['email' => $_GET['email']]);What to do in your own app
- Use parameterised queries everywhere, or an established ORM that does it for you. Never join user input into a query string.
- Look for the exceptions. Raw queries, hand-written search filters, sort options and reporting pages are where unsafe code hides. Search your code for places that build queries from strings.
- Limit what the database account can do. The app's database user usually doesn't need permission to drop tables or read everything. Smaller permissions mean a smaller blast radius.
- Validate input for type and length as a second layer. It won't replace parameterised queries, but it helps.
- Test it. Try odd characters such as a single quote in your search boxes and forms. A database error on screen is a warning sign worth a developer's attention.
The part that applies to everyone: your suppliers
Even if your code is spotless, tools you rely on may not be. A few habits make a real difference:
- Keep an inventory of the software and services that hold or process your customers' data.
- Apply security updates quickly, especially for anything reachable from the internet.
- Don't keep data you no longer need. Files sitting in a transfer tool for years are files that can be stolen years later.
- Know your plan for when a supplier tells you they've been breached: who to contact, what to check, what you'll tell customers.
Spotting unsafe queries and forgotten data is exactly the sort of thing a review of your live app can find. Our security checklist has the basics, and an audit goes into the parts a checklist can't reach.
Common questions
What is a SQL injection in simple terms?
It's when text typed into a form or web address gets treated as part of a database command instead of as plain data. That lets an attacker change what the database does.
Can SQL injection still happen with modern frameworks?
Yes. Frameworks help a lot, but raw queries, search filters and custom reports still get written by hand, and any one of them can be vulnerable. It's worth checking each place user input meets the database.
If a vendor gets hacked, is my business still responsible?
Often, yes, at least in the eyes of customers and regulators. Whose fault it was matters less than what data you handed over and how long you kept it.
Source: NVD: CVE-2023-34362
Not sure if your app has this problem?
Our $79 audit checks for issues like this and ranks what to fix first. No issues found? Full refund.
Get my audit · $79


