SQL Injection is one of the most dangerous and common web security vulnerabilities. It happens when attackers inject malicious SQL code into application queries to access, modify, or delete database data.
Applications developed using technologies like ASP.NET, PHP, Java, Node.js, Python, or any backend connected to a database can be vulnerable if queries are not handled properly.
What is SQL Injection?
SQL Injection occurs when user input is directly concatenated into SQL queries without validation or parameterization.
Vulnerable Example
string query = "SELECT * FROM Users WHERE Username='" + txtUsername.Text +
"' AND Password='" + txtPassword.Text + "'";
If a user enters:
' OR 1=1 --
Then the query becomes:
SELECT * FROM Users
WHERE Username='' OR 1=1 --'
AND Password=''
Since 1=1 is always true, authentication is bypassed.
Types of SQL Injection
1. Authentication Bypass
Used to login without valid credentials.
Attack Input
' OR '1'='1
2. Data Extraction
Attackers steal database information.
Example
UNION SELECT name, password FROM Users
3. Data Deletion
Attackers can delete records.
Example
'; DELETE FROM Users --
4. Blind SQL Injection
Attackers retrieve data indirectly using TRUE/FALSE conditions.
Example
' AND 1=1 --
Real-World Vulnerable Code Examples
Example 1: Vulnerable Login API in ASP.NET
Wrong Method
string query = "SELECT * FROM Users WHERE Email='" + email +
"' AND Password='" + password + "'";
SqlCommand cmd = new SqlCommand(query, con);
Problem
If attacker enters:
admin' --
The query becomes:
SELECT * FROM Users WHERE Email='admin' --' AND Password=''
Password check is skipped.
Proper Solution: Parameterized Query
Secure Method
string query = "SELECT * FROM Users WHERE Email=@Email AND Password=@Password";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("@Email", email);
cmd.Parameters.AddWithValue("@Password", password);
Why Secure?
The database treats input as data, not executable SQL.
Example 2: Search Function Vulnerability
Vulnerable Code
string query = "SELECT * FROM Products WHERE ProductName LIKE '%" + keyword + "%'";
Attack
%' OR 1=1 --
Secure Solution
string query = "SELECT * FROM Products WHERE ProductName LIKE @keyword";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("@keyword", "%" + keyword + "%");
Example 3: Dynamic SQL in Stored Procedure
Vulnerable Stored Procedure
CREATE PROCEDURE GetUser
@Name NVARCHAR(100)
AS
BEGIN
DECLARE @SQL NVARCHAR(MAX)
SET @SQL = 'SELECT * FROM Users WHERE Name=''' + @Name + ''''
EXEC(@SQL)
END
Dangerous Because
Attackers can inject SQL through @Name.
Secure Stored Procedure
CREATE PROCEDURE GetUser
@Name NVARCHAR(100)
AS
BEGIN
SELECT * FROM Users WHERE Name = @Name
END
Best Practices to Prevent SQL Injection
1. Always Use Parameterized Queries
Recommended
cmd.Parameters.Add("@Id", SqlDbType.Int).Value = id;
Avoid
WHERE Id=" + id
2. Use Stored Procedures Properly
Stored procedures are safe only if they avoid dynamic SQL concatenation.
Safe
SELECT * FROM Employee WHERE EmployeeID=@EmployeeID
Unsafe
SET @SQL='SELECT * FROM Employee WHERE ID=' + @ID
3. Validate User Input
Validate:
Length
Data type
Allowed characters
Email format
Numeric values
Example
if(!int.TryParse(txtId.Text, out int id))
{
return;
}
4. Apply Least Privilege Principle
Database users should only have required permissions.
Example
Application user should NOT have:
5. Hide Detailed Database Errors
Bad
SQL Exception near 'DROP TABLE'
Good
Something went wrong. Please try again.
Log actual errors internally.
6. Use ORM Frameworks
ORMs automatically parameterize queries.
Examples:
Entity Framework
Dapper
Hibernate
7. Sanitize Dynamic SQL Carefully
If dynamic SQL is unavoidable:
Secure Dynamic SQL
DECLARE @SQL NVARCHAR(MAX)
SET @SQL = 'SELECT * FROM Users WHERE Name=@Name'
EXEC sp_executesql
@SQL,
N'@Name NVARCHAR(100)',
@Name
SQL Injection Testing Examples
Common Payloads
' OR 1=1 --
admin' --
' UNION SELECT NULL,NULL --
'; DROP TABLE Users --
Secure Login API Example (.NET Core)
[HttpPost]
public IActionResult Login(LoginModel model)
{
using(SqlConnection con = new SqlConnection(connectionString))
{
string query = @"SELECT COUNT(*)
FROM Users
WHERE Email=@Email
AND Password=@Password";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("@Email", model.Email);
cmd.Parameters.AddWithValue("@Password", model.Password);
con.Open();
int count = (int)cmd.ExecuteScalar();
if(count > 0)
{
return Ok("Login Success");
}
else
{
return Unauthorized();
}
}
}
Additional Security Layers
Use These Together
| Security Measure | Purpose |
|---|
| Parameterized Queries | Prevent SQL execution |
| Input Validation | Block invalid data |
| WAF (Web Application Firewall) | Detect attacks |
| HTTPS | Secure transmission |
| Logging & Monitoring | Detect suspicious activity |
| Rate Limiting | Prevent brute force |
Common Developer Mistakes
| Mistake | Risk |
|---|
| String concatenation in SQL | Injection vulnerability |
| Trusting frontend validation | Attackers bypass frontend |
| Using admin DB account | Full database compromise |
| Dynamic SQL without validation | Remote execution |
| Exposing SQL errors | Information leakage |
Interview Questions on SQL Injection
Q1. What is SQL Injection?
SQL Injection is a vulnerability where attackers inject malicious SQL code through user input to manipulate database queries.
Q2. How do parameterized queries prevent SQL Injection?
Parameterized queries separate SQL commands from user data, preventing execution of malicious input.
Q3. Are Stored Procedures always safe?
No. Stored procedures using dynamic SQL concatenation can still be vulnerable.
Conclusion
SQL Injection remains one of the top cybersecurity threats because many applications still build queries using string concatenation.
The best protection methods are:
Following secure coding practices can prevent attackers from stealing or damaging sensitive database information.