SQL Server  

SQL Injection: Complete Guide with Examples and Proper Solutions

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:

  • DROP DATABASE

  • ALTER TABLE

  • DELETE access (if unnecessary)

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:

  • Use whitelist validation

  • Avoid direct concatenation

  • Use sp_executesql

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 MeasurePurpose
Parameterized QueriesPrevent SQL execution
Input ValidationBlock invalid data
WAF (Web Application Firewall)Detect attacks
HTTPSSecure transmission
Logging & MonitoringDetect suspicious activity
Rate LimitingPrevent brute force

Common Developer Mistakes

MistakeRisk
String concatenation in SQLInjection vulnerability
Trusting frontend validationAttackers bypass frontend
Using admin DB accountFull database compromise
Dynamic SQL without validationRemote execution
Exposing SQL errorsInformation 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:

  • Parameterized queries

  • Proper input validation

  • Secure stored procedures

  • Least privilege database access

  • ORM frameworks

  • Error handling and monitoring

Following secure coding practices can prevent attackers from stealing or damaging sensitive database information.