SQL injection from formatted SQL string in ADO.NET command

Critical Risk SQL Injection
csharpsql-injectionado-netdatabaseinjection

What it is

SQL injection vulnerability in C# applications using ADO.NET where user input is concatenated into SQL strings without proper parameterization, allowing attackers to manipulate database queries.

using System.Data.SqlClient;

public class UserService
{
    private string connectionString;

    public User GetUserById(string userId)
    {
        // VULNERABLE: Direct string concatenation
        string query = "SELECT * FROM users WHERE id = " + userId;

        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            SqlCommand command = new SqlCommand(query, connection);
            connection.Open();

            SqlDataReader reader = command.ExecuteReader();
            if (reader.Read())
            {
                return new User
                {
                    Id = reader.GetInt32("id"),
                    Name = reader.GetString("name"),
                    Email = reader.GetString("email")
                };
            }
        }
        return null;
    }
}

// Malicious input: GetUserById("1 OR 1=1 --")
// Results in: SELECT * FROM users WHERE id = 1 OR 1=1 --
using System.Data.SqlClient;

public class UserService
{
    private string connectionString;

    public User GetUserById(int userId)
    {
        // SECURE: Using parameterized query
        string query = "SELECT * FROM users WHERE id = @userId";

        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            SqlCommand command = new SqlCommand(query, connection);
            command.Parameters.AddWithValue("@userId", userId);
            connection.Open();

            SqlDataReader reader = command.ExecuteReader();
            if (reader.Read())
            {
                return new User
                {
                    Id = reader.GetInt32("id"),
                    Name = reader.GetString("name"),
                    Email = reader.GetString("email")
                };
            }
        }
        return null;
    }

    // Input validation version
    public User GetUserByIdSafe(string userIdStr)
    {
        // Validate input
        if (!int.TryParse(userIdStr, out int userId) || userId <= 0)
        {
            throw new ArgumentException("Invalid user ID");
        }

        return GetUserById(userId);
    }
}

💡 Why This Fix Works

The vulnerable code concatenates user input directly into the SQL query string, allowing SQL injection attacks. The fixed version uses parameterized queries with @userId placeholder and AddWithValue() to safely bind the parameter.

Why it happens

The query is built with formatted strings that include user input, rather than using parameters, allowing input to change SQL syntax.

Root causes

String Concatenation in SQL Queries

The query is built with formatted strings that include user input, rather than using parameters, allowing input to change SQL syntax.

Preview example – CSHARP
// VULNERABLE: String concatenation
string query = "SELECT * FROM users WHERE id = " + userId;
SqlCommand cmd = new SqlCommand(query, connection);
SqlDataReader reader = cmd.ExecuteReader();

String Interpolation Without Parameterization

Using C# string interpolation or String.Format to build SQL queries directly embeds user input into the SQL string.

Preview example – CSHARP
// VULNERABLE: String interpolation
string query = $"SELECT * FROM users WHERE name = '{userName}'";
// Allows injection like: userName = "'; DROP TABLE users; --"

Fixes

1

Use Parameterized Queries with SqlParameter

Use parameterized queries with SqlCommand and SqlParameter. Set CommandText with placeholders (e.g., @name) and add typed parameters.

View implementation – CSHARP
// SECURE: Parameterized query
string query = "SELECT * FROM users WHERE id = @userId";
SqlCommand cmd = new SqlCommand(query, connection);
cmd.Parameters.AddWithValue("@userId", userId);
SqlDataReader reader = cmd.ExecuteReader();
2

Avoid String Concatenation and Interpolation

Never concatenate or interpolate user input directly into SQL strings. Always use parameter placeholders and bind values separately.

View implementation – CSHARP
// AVOID: String concatenation
// string query = "SELECT * FROM users WHERE name = '" + userName + "'";

// USE: Parameterized approach
string query = "SELECT * FROM users WHERE name = @userName";
cmd.Parameters.AddWithValue("@userName", userName);

Detect This Vulnerability in Your Code

Sourcery automatically identifies sql injection from formatted sql string in ado.net command and many other security issues in your codebase.