CRITICAL aspnetsql injection union

Sql Injection Union in Aspnet

How Sql Injection Union Manifests in Aspnet

SQL injection via UNION in ASP.NET applications typically occurs when user-controlled input is concatenated directly into SQL query strings without proper parameterization, especially in legacy Web Forms or MVC controllers using SqlCommand with string interpolation. Attackers exploit this by injecting UNION SELECT statements to extract data from other tables, often bypassing authentication or enumerating schema information.

A common vulnerable pattern appears in login endpoints where username or password inputs are built into a query like:

string query = "SELECT * FROM Users WHERE Username = '" + username + "' AND Password = '" + password + "';";
SqlCommand cmd = new SqlCommand(query, connection);

An attacker can supply a username like: ' UNION SELECT NULL, password, NULL, NULL FROM Users --. The first NULL matches the column count, and the second extracts passwords. In ASP.NET, this often surfaces in Page_Load handlers, ApiController actions, or WCF services where raw input from Request.QueryString, Form, or JSON bodies is used directly in SQL.

Union-based injection is particularly effective in ASP.NET due to detailed error messages (when customErrors is off) revealing database structure, and the common use of DataSet or DataReader that returns multiple result sets, making data extraction via UNION feasible.

Aspnet-Specific Detection

Detecting UNION-based SQL injection in ASP.NET requires black-box testing that analyzes response differences when injecting payloads designed to test union viability. middleBrick performs this by sending sequential probes that incrementally test column counts and data types, observing changes in response length, status codes, or error messages.

For example, middleBrick might send:

  • id=1 ORDER BY 1-- to id=1 ORDER BY 10-- to determine column count
  • id=1 UNION SELECT NULL,NULL,NULL,NULL,NULL-- with varying data types (e.g., 'a', 1) to find which columns accept strings

In ASP.NET, successful UNION injection often manifests as:

  • 200 OK responses with altered data in UI controls (e.g., GridView showing unexpected rows)
  • Changes in JSON API responses where extra fields appear
  • Error messages like System.Data.SqlClient.SqlException: All queries in a UNION statement must have an equal number of expressions when column count is wrong
  • Blind boolean-based differences when UNION succeeds but returns no visible data

middleBrick’s LLM/AI security module does not directly test SQLi, but its core 12 checks include Input Validation which actively probes for UNION-based injection. When scanning an ASP.NET API endpoint like /api/products?id=5, middleBrick will test for UNION payloads and report findings with severity based on confirmed data extraction, referencing OWASP A03:2021 – Injection.

Aspnet-Specific Remediation

The definitive fix for UNION-based SQL injection in ASP.NET is to eliminate string concatenation in SQL queries and use parameterized queries via SqlParameter or ORM frameworks like Entity Framework Core. Never rely on input validation or escaping as a primary defense.

Replace vulnerable code such as:

// VULNERABLE: String concatenation
string sql = "SELECT * FROM Products WHERE Category = '" + category + "' AND Price < " + maxPrice;
using (SqlCommand cmd = new SqlCommand(sql, conn)) { ... }

With parameterized queries:

// FIXED: SqlParameter usage
string sql = "SELECT * FROM Products WHERE Category = @category AND Price < @maxPrice";
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
    cmd.Parameters.Add("@category", SqlDbType.NVarChar, 50).Value = category;
    cmd.Parameters.Add("@maxPrice", SqlDbType.Decimal).Value = maxPrice;
    using (SqlDataReader reader = cmd.ExecuteReader()) { ... }
}

In ASP.NET Core with Entity Framework Core, use LINQ or parameterized raw SQL:

// FIXED: EF Core parameterized query
var products = await _context.Products
    .FromSqlRaw("SELECT * FROM Products WHERE Category = {0} AND Price < {1}", category, maxPrice)
    .ToListAsync();

For legacy Web Forms using SqlDataSource, switch to SelectParameters:

<asp:SqlDataSource 
    SelectCommand="SELECT * FROM Products WHERE Category = @Category"
    runat="server">
    <SelectParameters>
        <asp:ControlParameter ControlID="CategoryDropdown" Name="Category" PropertyName="SelectedValue" />
    </SelectParameters>
</asp:SqlDataSource>

Additionally, enforce least-privilege database access: the ASP.NET app’s database user should only have SELECT on required tables, not access to administrative schemas. Enable customErrors in web.config to prevent error message leakage that aids UNION injection reconnaissance.

Frequently Asked Questions

Can middleware like ASP.NET Core's built-in request filtering prevent UNION SQL injection?
No. ASP.NET Core middleware (e.g., UseRouting, UseEndpoints) does not inspect or sanitize SQL query inputs. Protection must occur at the data access layer via parameterized queries or ORM safe methods. Relying on middleware for SQLi prevention is ineffective and creates a false sense of security.
Does using <code>HttpUtility.HtmlEncode</code> or <code>AntiXssEncoder</code> protect against UNION SQL injection in ASP.NET?
No. HTML encoding prevents cross-site scripting (XSS) by neutralizing HTML/JavaScript in output contexts. It has no effect on SQL syntax. SQL injection requires context-specific handling—parameterization for SQL, not encoding. Using HTML encoding for SQLi protection is a common misconception that leaves applications vulnerable.