SQL Injection
- Pronunciation
- ES-kyoo-EL in-JEK-shun or SEE-kwul in-JEK-shun
In short
SQL injection is an attack where user input is treated as part of a database query, letting an attacker read, change, or delete data they should not reach.
What is SQL injection?
SQL injection happens when an application builds a SQL query by gluing user input directly into the query text. If the input contains SQL syntax, the database cannot tell it apart from the developer's code and runs it, changing what the query does.
The classic illustration is a login check that inserts the typed username straight into WHERE name = '...'. Entering ' OR '1'='1 closes the quote and adds a condition that is always true, so the query may match every user in the table. Real attacks can dump entire tables, bypass logins, or alter records.
The reliable defense is parameterized queries, also called prepared statements. Instead of building a string, you send the query with placeholders and pass the values separately, so the database always treats them as data, never as code. ORMs and query builders do this by default, and input validation, least-privilege database accounts, and hiding raw database errors from users limit the damage if something slips through.
Escaping quotes by hand or blocking suspicious words is not a reliable fix, because attackers find ways around filters. SQL injection is related to XSS: both are injection flaws where data is mistaken for code, but SQL injection targets the database on the server while XSS targets the user's browser.
At a glance
Key takeaways
- SQL injection occurs when user input becomes part of a query's code.
- It can expose, modify, or delete data and bypass logins.
- Parameterized queries are the primary defense.
- ORMs help, but their raw query methods can still be vulnerable.
- Least-privilege database accounts limit the damage of an attack.
Example
const email = req.body.email; // untrusted input from a form
// Vulnerable: input is pasted into the SQL text and can change the query
const bad = await db.query(
`SELECT * FROM users WHERE email = '${email}'`
);
// Safe: the value is sent separately and is always treated as data
const good = await db.query(
"SELECT * FROM users WHERE email = $1",
[email]
);Readers ask
How do you prevent SQL injection?
Use parameterized queries or prepared statements for every query that includes outside data, so values are never interpreted as SQL. Add input validation, least-privilege database accounts, and careful error handling as extra layers.
Do ORMs prevent SQL injection?
ORMs use parameterized queries for their normal methods, which prevents most SQL injection. However, raw SQL features in an ORM can still be vulnerable if you build query strings from user input.
Can NoSQL databases be attacked with injection too?
Yes. NoSQL injection is a similar attack where untrusted input changes the structure of a query, for example by passing an object containing query operators instead of a plain string. The fix follows the same idea: validate input types and never build queries directly from raw input.
Often compared
See also
- SQLDatabases, p. 40SQL is the standard language for working with relational databases, used to create tables and to insert, query, update, and delete the data stored in them.
- DatabaseDatabases, p. 6A database is an organized collection of data stored on a computer, managed by software that lets applications save, search, and update it efficiently.
- ORMDatabases, p. 33An ORM is a library that maps database tables to objects in your programming language, letting you read and write data with code instead of raw SQL.
- XSSSecurity, p. 48XSS is a vulnerability that lets an attacker inject malicious JavaScript into a trusted website so that it runs in other users' browsers.
- NoSQLDatabases, p. 29NoSQL is a family of databases that store data in models other than relational tables, such as documents, key-value pairs, wide columns, or graphs.
Sources
Spotted a mistake or something missing on this page?Suggest an edit