Slips that give the teller orders
Watch it happen
Mallory writes an order inside the name box of a slip. The teller reads the entire slip aloud as one instruction, and the vault is emptied.
Two customers walk in to make a deposit. Alice heads to the window with her slip. Mallory follows right behind.
In bank terms and app terms
| In the bank | In your app |
|---|---|
Are you exposed?
You build queries with template strings, like SELECT * FROM users WHERE name = '${name}'.You pass user input to a shell command, eval, or a template engine, or put raw JSON from the client into a Mongo query.Your API returns raw database error messages when something odd is sent.
Use parameterized queries or your ORM’s safe methods. Never paste input into the query text, and give raw-query helpers parameters too. Escaping and blocklists are weaker backups. For commands, avoid the shell entirely and pass arguments as a list. Check input against an allowlist of expected shapes. Give the database user only the permissions it needs, and return generic errors instead of database messages.
It has happened to real companies
Heartland Payment Systems (2008) — In 2009 US prosecutors indicted Albert Gonzalez and two others, alleging they used SQL injection against poorly coded web applications to steal 130 million credit and debit card numbers from Heartland and other companies, including Hannaford Bros. and 7-Eleven.
Sony Pictures (2011) — In June 2011 the LulzSec group said it had used "a very simple SQL injection" to take unencrypted personal data on over 1 million people from Sony Pictures websites. Two LulzSec members were later sentenced in the US over the intrusion, which used SQL injection against a Sony Pictures film website.
What it looks like in code
// BAD: String concatenation in SQL query
const filter = `status = '${userInput}'`
const result = await sql.unsafe(`SELECT * FROM tasks WHERE ${filter}`)
// BAD: A plain function call with an interpolated string (not a tagged template)
const result = await sql.unsafe(`SELECT * FROM users WHERE name = '${name}'`)
// BAD: Command execution with user input
const output = execSync(`convert ${uploadedFile} output.png`)
Ask your AI tool to fix it
Paste this into Cursor, Claude, Lovable, Bolt or whatever you build with.
Audit this codebase for injection. Find every place user input reaches a SQL query, NoSQL filter, shell command, eval or template. Replace string concatenation with parameterized queries or safe ORM calls, validate NoSQL inputs as plain strings or numbers, and avoid shell execution (use argument arrays). Return generic error messages. List each change.Where this comes from
The facts, figures and fixes on this page were checked against these sources on 25 Oct 2026. They are linked so you can check for yourself.
- SQL Injection Prevention Cheat SheetOWASPParameterized queries first; escaping is a weaker backup; least privilege for the database user
- OS Command Injection Defense Cheat SheetOWASPAvoid the shell, pass arguments as a list, validate input against an allowlist
- NoSQL injectionPortSwigger Web Security AcademyRaw JSON from the client can smuggle in NoSQL operators such as $ne
- SQL injection attacks led to Heartland, Hannaford breachesComputerworld2009 indictment of Albert Gonzalez: SQL injection, 130 million cards, Heartland, Hannaford, 7-Eleven
- LulzSec Hacks SonyPictures.com; 1 Million Accounts ExposedPCWorldLulzSec's 2011 claim of a "very simple SQL injection" on Sony Pictures sites
- Second Hacker Sentenced In Sony Pictures Cyber AttackCBS News Los AngelesLulzSec members sentenced in the US for a SQL injection attack on a Sony Pictures website
Spot a mistake or something out of date? Report a correction · How these guides are made and checked
The free, open-source scanner checks for most of the problems in these guides.