Frontend sends input
A form collects a username, email address, password, or search term.
visitor@learn:~$ cat sql-injection.html
SQL injection happens when an application mixes user-controlled text directly into a database query. The database can no longer reliably tell the difference between data and instructions.
A form collects a username, email address, password, or search term.
An unsafe backend inserts that value directly into SQL using string concatenation.
If the input contains SQL syntax, the finished query may behave differently from intended.
The double quotes belong to the programming language building the text string. The single quotes will appear inside the final SQL statement to mark a text value.
"... username = '"
+
"student01"
+
"'"
=
username = 'student01'
SELECT email FROM users WHERE username = ?
Separate parameter value:
The value is treated as data, not SQL code.
A typical login query checks whether one row matches both the submitted username and password. If the application builds this query by concatenating strings, SQL syntax entered into either field can change the logic.
SELECT * FROM users WHERE username = 'clint' AND password = 'SuperSecretPassword'
They may add an OR condition that is always true, or comment out the rest of the password check.
username = 'administrator' -- password = doesNotMatter
SELECT * FROM users WHERE username = 'administrator' -- AND password = 'doesNotMatter'
Search pages often place user input directly in the URL, then use it in a LIKE query.
/search?term=eggs SELECT * FROM recipes WHERE content LIKE '%" + searchText + "%'
An injected value like %' OR '1'='1' -- can force the search to match everything.
Some database drivers allow more than one statement. That can turn one input into a read plus a destructive or unauthorized write.
' OR '1'='1'; INSERT INTO users (username, password) VALUES ('attacker', 'password'); --
Whether stacked queries work depends on the database, driver, and server configuration.
Treat every value that travels from the client to the server as untrusted, even if it comes from a hidden field, cookie, header, or authenticated user.
Forms, search bars, URL parameters, hidden fields, cookies, HTTP headers, API parameters, and uploaded metadata.
Unexpected results, empty result sets, full SQL errors, database names, table names, file paths, or stack traces.
Some successful SQLi attempts are blind: the page may show no obvious error or confirmation at all.
SQL comments cause a parser to ignore part of a statement. The accepted comment forms differ slightly between database products.
const query = "SELECT * FROM users WHERE username='" + username + "'";
The user's value becomes part of the instruction text.
const query = "SELECT * FROM users WHERE username = ?"; db.all(query, [username], callback);
The query structure stays fixed while the value is supplied separately.
Reject invalid input before use. Check allowed characters, length, formats, and fields that should not contain spaces or SQL syntax.
Escaping or removing risky characters can reduce risk, but filtering is not a replacement for prepared statements.
Do not expose raw SQL errors, database versions, table names, internal file paths, or stack traces to users.
MySQL / MariaDB
--requires whitespace after the dashes.PostgreSQL
SQL Server
Oracle
SQLite