← Back to MySQL Course | Chapter 18: User Management & Security | Lesson 5 of 6

MySQL SQL Injection

What Is SQL Injection?

SQL injection happens when untrusted input, such as text typed into a login form, gets concatenated directly into a SQL query string, letting an attacker inject their own SQL logic into your query. A classic example is building a query like "SELECT * FROM users WHERE username = '" + input + "'", where an attacker can enter a value that changes the query's meaning entirely rather than just supplying a username.

Example: What Is SQL Injection?

sql
-- Vulnerable: username comes from raw, unescaped user input
SET @input = "' OR '1'='1";
-- SELECT * FROM users WHERE username = '' OR '1'='1';  -- matches every row

Why It Is Dangerous

A successful injection can let an attacker bypass authentication entirely, read data they should never see, modify or delete rows, or in some configurations even execute administrative database commands. Because the malicious input is treated as executable SQL rather than as plain data, the damage is not limited to what the application's own logic normally allows.

Example: Why It Is Dangerous

sql
-- A crafted input can bypass a login check entirely:
-- WHERE username = '' OR '1'='1' -- ' AND password = 'anything'
-- Everything after the -- becomes a comment, so the password check never runs

Prepared Statements Prevent It

Prepared statements separate the SQL structure from the data values: the query is compiled with placeholders first, and the actual input is sent afterward as pure data that can never be reinterpreted as SQL syntax. This is the standard, reliable defense against injection, because the database driver -- not string concatenation -- handles escaping the values correctly every time.

Example: Prepared Statements Prevent It

sql
PREPARE stmt FROM 'SELECT * FROM users WHERE username = ?';
SET @uname = "' OR '1'='1";
EXECUTE stmt USING @uname;
DEALLOCATE PREPARE stmt;

Escaping as a Weaker Fallback

Manually escaping special characters (like doubling quotes or using a function such as mysql_real_escape_string in older APIs) can reduce injection risk, but it is fragile and easy to get wrong -- forgetting to escape even one input point reopens the vulnerability. Prepared statements are strongly preferred because they remove the need to reason about escaping at all.

Example: Escaping as a Weaker Fallback

sql
-- Escaping only helps if every single input point is escaped correctly:
SELECT QUOTE("O'Brien") AS escaped_value;

Least-Privilege Accounts

Even with prepared statements in place, applications should connect to the database using an account with only the privileges it actually needs, never a root or admin account. If an injection attack or another vulnerability does slip through, a least-privilege account limits the damage to what that account is allowed to do, rather than exposing the whole server.

Example: Least-Privilege Accounts

sql
CREATE USER 'app_readonly'@'localhost' IDENTIFIED BY 'pass123';
GRANT SELECT ON mydb.* TO 'app_readonly'@'localhost';
-- Never connect the application as root
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.