Learn how SQL Injection works, why vulnerable applications can be manipulated through user input, how to identify SQL Injection safely, and how developers prevent it using parameterized queries. This beginner-friendly lesson combines SQL fundamentals, web security concepts, practical examples, and hands-on exercises.
Author
Abhishek Singh
Published
12 min read
SQL Injection Explained for Beginners
SQL Injection, commonly called SQLi, is a web application vulnerability that occurs when an application incorrectly handles user-controlled input while constructing a SQL query.
SQL Injection is one of the most important vulnerabilities to understand when learning web application security.
It teaches a fundamental security principle:
User input should never be trusted as application code.
In this lesson, we'll start with the basics and gradually move toward practical SQL Injection testing.
You will learn:
What SQL is
How web applications communicate with databases
What SQL Injection means
Why SQL Injection happens
Where SQL Injection can occur
How to recognize possible SQL Injection
Boolean-based SQL Injection concepts
Error-based SQL Injection concepts
Blind SQL Injection concepts
How Burp Suite can help during authorized testing
How developers prevent SQL Injection
How to practice safely in a Hackvora lab
What Is SQL?
Before understanding SQL Injection, we need to understand SQL.
SQL stands for:
Structured Query Language
It is commonly used to communicate with relational databases.
For example, an application might have a database containing users:
TERMINAL OUTPUT
users
├── id
├── username
├── email
├── password_hash
└── role
A SQL query could retrieve a user:
TERMINAL OUTPUT
SELECT username, email, role
FROM users
WHERE username ='alice';
The database receives the query, processes it, and returns the requested information.
How a Web Application Uses a Database
A typical web application looks like this:
TERMINAL OUTPUT
User
↓
Browser
↓
Web Application
↓
Database
For example, imagine a login page:
TERMINAL OUTPUT
Username: alice
Password: ********
The browser sends the credentials to the application.
Reader discussion
COMMENTS 1
No comments yet. Start the conversation.
The application then communicates with the database.
Conceptually:
TERMINAL OUTPUT
Browser
↓
Login Request
↓
Web Application
↓
SQL Query
↓
Database
↓
Result
↓
Web Application
↓
Browser
The important security boundary is between:
TERMINAL OUTPUT
User Input
↓
Application
↓
SQL Query
If the application incorrectly combines user input with SQL syntax, SQL Injection can occur.
What Is SQL Injection?
SQL Injection occurs when an application allows user-controlled input to influence the structure or meaning of a SQL query.
Consider a vulnerable application that creates a query like:
TERMINAL OUTPUT
const query =
"SELECT * FROM users WHERE username = '" + username + "'";
If the user enters:
TERMINAL OUTPUT
alice
the application creates:
TERMINAL OUTPUT
SELECT*FROM users WHERE username ='alice';
That appears normal.
The problem is that the application is building SQL by concatenating a SQL string and user input.
The application is effectively doing:
TERMINAL OUTPUT
SQL code
+
User input
=
SQL query
That is the fundamental design problem.
Data vs Code
One of the most important ideas in application security is separating data from instructions.
Consider:
TERMINAL OUTPUT
alice
The application should treat this as:
TERMINAL OUTPUT
DATA
It should not allow the user to turn the input into:
TERMINAL OUTPUT
SQL INSTRUCTIONS
A secure application maintains this separation:
TERMINAL OUTPUT
User Input
↓
Parameter
↓
SQL Query
↓
Database
A vulnerable application may effectively do:
TERMINAL OUTPUT
User Input
↓
String Concatenation
↓
SQL Query
↓
Database
This distinction is the foundation of SQL Injection.
Where Can SQL Injection Occur?
SQL Injection can potentially occur anywhere user-controlled data reaches an unsafe database query.
Common locations include:
Login Forms
TERMINAL OUTPUT
Username
Password
Search Fields
TERMINAL OUTPUT
Search products
URL Parameters
TERMINAL OUTPUT
/products?id=10
Filters
TERMINAL OUTPUT
/products?category=5
API Parameters
TERMINAL OUTPUT
{"userId":"10"}
Cookies
Applications sometimes use cookie values when querying databases.
HTTP Headers
Certain applications may use header values when constructing database queries.
The important question is not:
"Is this a login page?"
Instead ask:
Does user-controlled data reach a database query in an unsafe way?
A Simple Example
Imagine a product page:
TERMINAL OUTPUT
https://example.test/product?id=10
The application might construct:
TERMINAL OUTPUT
SELECT*FROM products
WHERE id =10;
The parameter is:
TERMINAL OUTPUT
id=10
A security tester can investigate how the application behaves when this value changes.
For example:
TERMINAL OUTPUT
10
may return:
TERMINAL OUTPUT
Product found
while another unexpected value might produce:
TERMINAL OUTPUT
Product not found
or potentially an application/database error.
The first objective during testing is not to exploit the application.
It is to understand:
Does this input influence database behavior?
Establish a Baseline
Before testing an application, establish a normal response.
For example:
TERMINAL OUTPUT
GET /product?id=10 HTTP/1.1
Host: lab.example
Record:
HTTP status code
Response size
Response content
Redirects
Response time
Example:
TERMINAL OUTPUT
Status: 200
Response size: 18 KB
Response time: 120 ms
This becomes your baseline.
Later, when you change the parameter, you can compare the responses.
Testing One Parameter at a Time
A common beginner mistake is changing many things at once.
Instead:
TERMINAL OUTPUT
Request A
↓
Normal parameter
Request B
↓
Modified parameter
Compare the results.
For example:
TERMINAL OUTPUT
id=10
versus:
TERMINAL OUTPUT
id=<test value>
Observe:
TERMINAL OUTPUT
Status
Response
Response length
Errors
Timing
This makes your testing more systematic.
SQL Errors
Sometimes an application exposes database errors.
For example:
TERMINAL OUTPUT
Database error
or:
TERMINAL OUTPUT
SQL syntax error
Such errors may reveal that user input is reaching a database query.
Depending on the application, errors might expose information about:
Database technology
Query structure
Tables
Columns
Application framework
This is why production applications should avoid exposing raw database errors.
A safer response is:
TERMINAL OUTPUT
Unable to process your request.
while the detailed error is recorded securely on the server.
Boolean Logic
Boolean logic is extremely useful when learning SQL Injection.
A condition can evaluate to:
TERMINAL OUTPUT
TRUE
or:
TERMINAL OUTPUT
FALSE
For example:
TERMINAL OUTPUT
TRUE AND TRUE
results in:
TERMINAL OUTPUT
TRUE
while:
TERMINAL OUTPUT
TRUE AND FALSE
results in:
TERMINAL OUTPUT
FALSE
SQL queries frequently use conditions:
TERMINAL OUTPUT
SELECT*FROM users
WHERE username ='alice'AND role ='user';
The database evaluates these conditions.
SQL Injection techniques can sometimes manipulate these conditions when an application is vulnerable.
Authentication and SQL Injection
Login functionality is a common area for SQL Injection testing.
A vulnerable application might conceptually build:
TERMINAL OUTPUT
SELECT*FROM users
WHERE username ='USER_INPUT'AND password ='PASSWORD_INPUT';
The security problem is not the SQL statement itself.
The problem is how the application creates it.
If untrusted input becomes part of the SQL syntax, an attacker may be able to alter the logic of the query.
In an authorized lab, this is useful for understanding how authentication can fail when application input is not safely handled.
Error-Based SQL Injection
Error-based SQL Injection relies on database errors or application behavior that reveals information.
Repeated timing behavior can indicate that a database condition is affecting execution.
However, network latency and server load can also cause delays.
Therefore:
One slow request is not evidence by itself.
UNION-Based SQL Injection
SQL supports the UNION operator.
For example:
TERMINAL OUTPUT
SELECT username
FROM users
UNIONSELECT username
FROM administrators;
UNION combines compatible query results.
If an application is vulnerable to UNION-based SQL Injection, attackers may potentially manipulate a query to retrieve information outside the application's intended query.
This is one reason SQL Injection can become a serious data exposure vulnerability.
Using Burp Suite
Burp Suite is commonly used during authorized web application testing.
A basic workflow is:
TERMINAL OUTPUT
Browser
↓
Burp Proxy
↓
Web Application
↓
Database
You can capture a request and send it to Repeater.
Repeater allows you to:
Modify parameters
Resend requests
Compare responses
Observe status codes
Compare response sizes
Observe response timing
For example:
TERMINAL OUTPUT
GET /product?id=10 HTTP/1.1
Host: lab.example
You can then modify the id parameter and compare the results.
The interpreter changes depending on the vulnerability.
Hands-On Practice
Now it's time to move from theory to practice.
In the Hackvora hands-on environment, you should work with a deliberately vulnerable application.
Your objective is not to attack a real website.
Instead, you'll learn how a controlled application processes input.
Task 1 — Identify the Input
Open the provided lab application.
Find the parameter used to retrieve a product.
Example:
TERMINAL OUTPUT
/product?id=1
Goal
Identify:
TERMINAL OUTPUT
Parameter:
________
Hint
Look at the URL and identify the value that changes when you request a different product.
Task 2 — Establish a Baseline
Send a normal request.
Example:
TERMINAL OUTPUT
/product?id=1
Record:
TERMINAL OUTPUT
HTTP Status:
Response:
Response Size:
Goal
Understand what a normal request looks like before testing.
Task 3 — Change the Parameter
Change only the identified parameter.
Observe:
TERMINAL OUTPUT
Status
Response
Response length
Errors
Timing
Goal
Determine whether changing the parameter changes application behavior.
Task 4 — Investigate the Behavior
Use the Hackvora lab's provided test input.
Compare:
TERMINAL OUTPUT
Normal request
with:
TERMINAL OUTPUT
Lab test request
Look for differences.
Goal
Determine whether the parameter appears to influence database behavior.
Task 5 — Understand the Vulnerability
Review the vulnerable application's query.
Identify where user input is being inserted into SQL.
Conceptually:
TERMINAL OUTPUT
"SELECT ... WHERE id = " + userInput
Goal
Identify the root cause.
Task 6 — Fix the Vulnerability
Modify the application to use a parameterized query.
Change the design from:
TERMINAL OUTPUT
String concatenation
to:
TERMINAL OUTPUT
Parameterized query
Goal
Verify that the user's input is treated as data rather than SQL syntax.
Think Like a Security Tester
When testing web applications, don't immediately ask:
"What payload should I use?"
Instead ask:
TERMINAL OUTPUT
Where does my input go?
↓
Does it reach a database?
↓
How is the query constructed?
↓
Is my input treated as data?
↓
Can application behavior change?
This mindset is much more valuable than memorizing payloads.
Think Like a Developer
Now look at the same vulnerability from the defensive side.
Ask:
TERMINAL OUTPUT
Where does user input enter the application?
↓
Where is it validated?
↓
Where is it used?
↓
Is the query parameterized?
↓
What permissions does the database account have?
↓
What information is exposed on errors?
Good security requires both perspectives.
SQL Injection Checklist
For Security Testers
TERMINAL OUTPUT
☐ Identify user-controlled parameters
☐ Establish a baseline
☐ Modify one input at a time
☐ Compare responses
☐ Investigate database errors
☐ Check repeatability
☐ Confirm the vulnerability
☐ Determine impact
☐ Document evidence
☐ Recommend remediation