Back to course

Preventing SQL Injection

TL;DR: Never build SQL queries with string concatenation. Use parameterized queries or prepared statements, every time, without exception.

string concatenation”SELECT * FROM usersWHERE id = ” + userIduserId = “1 OR 1=1” dumps entire tableparameterized query”SELECT * FROM usersWHERE id = ?” [userId]input treated as data, never as code

SQL injection has been on the OWASP Top 10 for over two decades. It’s not a new problem. It persists because it’s easy to introduce without realizing it, especially when you’re moving fast and just concatenating a variable into a query.

Here’s the attack in plain terms: if your query is built by joining strings together, an attacker can insert their own SQL by crafting a malicious input. Something like ' OR '1'='1 appended to a login field can return every row in your users table.

The fix is parameterized queries. Instead of inserting the user’s value directly into the query string, you pass it separately. The database treats it as a value, not as executable SQL.

const query = 'SELECT * FROM users WHERE username = ?';
connection.query(query, [username], (err, results) => {
  // Handle results
});

This one habit prevents the vast majority of SQL injection attacks. If you’re using an ORM, it usually handles this for you, but it’s worth knowing what’s happening underneath.

Further reading: OWASP SQL Injection Prevention Cheat Sheet