SQL Injection
How text you type into a form turns into a command inside the database, why it happens, and how to stop it for good.
- Track
- Web security
- Estimated time
- 30 min
- Level
- Beginner
Before this lesson
Most websites keep their data in a database and talk to it in a language called SQL. When an application builds SQL commands by pasting what you typed straight into them, you can write not data but commands. That is SQL Injection.
What is the vulnerability?
Take a login form. The application wants to ask the database: is there a user with this name and password? So it builds this command by pasting in what you typed:
const sql = "SELECT * FROM users WHERE username = '" + username +
"' AND password = '" + password + "'";If you type the username sara and the password 1234, the command becomes:
SELECT * FROM users WHERE username = 'sara' AND password = '1234'The problem is that the The ' character that surrounds text in SQL. What is between a pair of them is treated as text; what is outside them is treated as commands. that separates text from commands is something the user can type too.
Why does it happen?
It happens because the application mixed two different things in one place: the commands the programmer wrote, and the data the user entered. The database receives a single string and has no way to know which part came from the programmer and which from the user, so it runs all of it.
Vulnerable code example
If you type this into the username box:
admin'--the command the database runs becomes:
SELECT * FROM users WHERE username = 'admin'-- ' AND password = '...'The quote closed the name after admin, and -- in SQL means “ignore the rest of the line”, so the password check disappeared entirely. The result: you logged in as the admin without knowing the password.
Real-world impact
SQL Injection is one of the most dangerous and best-known web vulnerabilities, and it still shows up today. As the web-security community tracks it, it can lead to:
- Bypassing login and signing in as any user.
- Reading data that is not yours: user records, stored passwords, internal information.
- In the worst cases, changing or deleting data.
Try it yourself
This lesson has three labs in order, each harder than the last:
- Login bypass (easy): no protection, and the page shows you the command it ran.
- Past a word filter (medium): there is partial “protection”, and you will see why it is not enough.
- Blind injection (hard): no data is shown, and you extract the secret with repeated yes/no questions.
Try them in the labs section below. The next level unlocks once you solve the one before it.
How it is prevented
The correct and only fix is parameterized queries (also called prepared statements): we write the command text as a fixed template with blanks, and pass the values separately.
// The command text is fixed; the values are passed separately as data and never become commands.
const user = db.get(
'SELECT id, role FROM users WHERE username = ? AND password_hash = ?',
[username, hash]
);This way, whatever quotes or SQL words you type into the box, they stay a plain text value that is compared, and can never become part of the command.
Labs
Login bypass
SolvedEasyBrowser lab
Log in as the admin account without knowing its password.
Enter the labLockedPast a word filter
SolvedMediumBrowser lab
Extract the voucher code from the notes table, then enter it in the voucher box.
Enter the labLockedBlind injection
SolvedHardBrowser lab
Extract the admin's full reset token, then enter it.
Enter the labLocked
