StackHawk

.NET SQL Injection Guide: Examples and Prevention

StackHawk   |   Jul 17, 2025

LinkedIn
X (Twitter)
Facebook
Reddit
Subscribe To StackHawk Posts

If you’re developing .NET applications that interact with databases, you’ve likely encountered SQL injection vulnerabilities at some point in your career (whether you’ve noticed it or not). These security flaws remain one of the most prevalent and dangerous threats in web application development, consistently ranking in the OWASP Top 10 security risks.

SQL injection attacks can compromise your entire application and database, potentially exposing sensitive user data, allowing unauthorized data manipulation, or even enabling complete system takeover. Understanding how these attacks work and how to prevent them is crucial for any .NET developer working with data-driven applications.

This guide will help you understand SQL injection vulnerabilities specific to .NET applications and provide practical guidance on how to identify, fix, and prevent them. We’ll also demonstrate how to utilize automated security testing tools, such as StackHawk, to verify your defenses continuously. Let’s start by understanding what SQL injection is and why it poses such a significant risk.

What Is SQL Injection?

SQL injection is a code injection technique where malicious actors insert or “inject” SQL code into application queries through user input fields. This occurs when an application fails to properly validate, sanitize, or parameterize user input before incorporating it into SQL statements.

When successful, SQL injection enables attackers to manipulate the queries that an application sends to its database. In web applications, common entry points for SQL injection attacks include form fields, URL parameters, and any other input mechanism that feeds data into database queries.

How does a SQL injection attack work? The attack exploits the way applications construct SQL queries by concatenating user input directly into query strings. When user input isn’t properly handled, attackers can manipulate the structure and logic of SQL statements, causing them to behave differently than intended.

A successful SQL injection attack can have severe consequences:

  • Data theft: Unauthorized access to sensitive information like user credentials, personal data, or business-critical information
  • Data manipulation: Unauthorized insertion, modification, or deletion of database records
  • System compromise: In severe cases, attackers may gain administrative access to the database server or underlying system

The financial, legal, and reputational damage from successful SQL injection attacks can be devastating for organizations of any size.

SQL Injection in .NET: A Practical Example

Let’s examine how SQL injection vulnerabilities commonly occur in .NET applications with a practical example.

Consider a blog application built with .NET that uses URL slugs to retrieve posts. A slug is a URL-friendly version of a post title, typically used in clean URLs like /posts/my-first-blog-post. The application must query the database to retrieve the post with the matching slug.

A developer might implement this functionality using string concatenation:

var query = "SELECT Title, Body, Excerpt FROM Post WHERE Slug = '" + slug + "' ORDER BY Published DESC";

// query execution, etc

This approach creates a significant security vulnerability. Since the slug variable is directly derived from user input via the URL and concatenated into the SQL query without any validation or sanitization, the application becomes susceptible to SQL injection attacks. The malicious actor could edit the URL so it looks like this:

<YOUR-DOMAIN-NAME>/posts/'; DROP TABLE Post;--

The string concatenation would result in the following query:

SELECT Title, Body, Excerpt FROM Post WHERE Slug = ''; DROP TABLE Post;--' ORDER BY Published DESC

As you can see, the single quote provided by the malicious actor matched the opening one already existing within the query. Then, the malicious query emits a DROP TABLE statement. Following that, it includes the “–” character, which causes everything else to be considered a comment.

How to Prevent .NET SQL Injection

As you’ve seen, SQL injection attacks can deal a devastating blow to your application. How can you avoid that?

Much of the advice for preventing SQL injections focuses on “sanitizing your input.” While distrusting all user input is a wise choice in general, sanitizing inputs won’t suffice as a solution. So, what are the valid solutions?

Validating Input

Often, the methods in your application will accept only a small subset of all possible values as valid. For instance, if your ASP.NET Core app has an action that gets an integer as a parameter, there’s really no reason to allow it to receive a string. Indicating the correct type in the action method will cause attempts to pass anything that’s not an integer to fail.

Using Allowlists

This is a continuation of the previous idea. In some situations, the set of valid values will be small enough that you’ll be able to create a list with all of them. For instance, consider a bug-tracking system that allows you to filter tickets by severity (e.g., low, medium, high, critical). Since the set of possible values is so small, the application code can keep the whole list in memory and validate the URL parameters. If it’s not on the list, it’s a hard no.

Using Parametrized Queries

The most effective method for avoiding .NET SQL injections, or injections in any other technology stack, is to use parametrized queries.

Parametrized queries avoid SQL injection in a clever way: You simply don’t include the user-provided values in the query at all. They are provided to the database separately and are never part of the SQL query text itself.

The query in our previous example would be written like this:

var query = "SELECT Title, Body, Excerpt FROM Post WHERE Slug = @slug ORDER BY Published DESC";

We avoid string concatenation by using a placeholder for the slug, but how do we pass the actual value?

After creating a new SqlCommand, you would add a new parameter using the AddWithValue method:

var query = "SELECT Title, Body, Excerpt FROM Post WHERE Slug = @slug ORDER BY Published DESC";
var command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("@slug", slug);

Note that while AddWithValue() is convenient and works well for most cases, it can sometimes lead to type inference issues or performance problems. For more precise control, especially with specific data types, consider using the Add() method with explicit type specification, like so:

command.Parameters.Add("@id", SqlDbType.Int).Value = userId;

Using The Principle of Least Privilege

A great security practice, not only for avoiding SQL injections, but in general, is what’s sometimes called the principle of least privilege. It simply means always choosing the least possible privilege for executing any sensitive action. For instance, if you’re integrating with an API and need to generate a token, ensure you only grant the permissions you’ll actually use in your app, and nothing more.

In the case of databases, the principle of least privilege means using database logins that can only do the bare minimum. Remember our first example? The malicious SQL code generated was this:

SELECT Title, Body, Excerpt FROM Post WHERE Slug = ''; DROP TABLE Post;--' ORDER BY Published DESC

If the application’s connection string used a database account with just reading privileges, the malicious query above wouldn’t be able to cause any harm.

Why Automated SQL Injection Testing Matters

SQL injection vulnerabilities are among the most critical security issues in web applications, consistently ranking in the OWASP Top 10. Manual testing often misses edge cases, and it’s challenging to test every possible input combination that could expose vulnerabilities.

A common mistake when developing .NET applications is assuming that basic input validation is sufficient protection against SQL injection. However, vulnerabilities can be introduced in subtle ways – through dynamic query construction, improper use of ORMs, or overlooked endpoints that bypass validation layers.

One of the most trusted security platforms for this type of testing is StackHawk. By using StackHawk to test for SQL injection vulnerabilities in your .NET applications and APIs, you get:

  • Early detection of SQL injection issues during development
  • Automated testing of complex injection scenarios you might not think to test manually
  • Clear remediation guidance with specific examples of vulnerable requests
  • Verification that fixes don’t introduce new security issues

By integrating SQL injection security testing into your development workflow, you can ensure that your application handles user input safely while maintaining functionality.

Validating Your SQL Injection Defenses with StackHawk

Once you’ve implemented parameterized queries and input validation, it’s crucial to ensure your defenses are comprehensive and effective. A common mistake is fixing obvious SQL injection vulnerabilities but missing less apparent attack vectors in other endpoints or edge cases.

This is where automated security testing becomes invaluable. Instead of manually testing every possible injection scenario and hoping you haven’t missed any vulnerable code paths, you can use StackHawk to automatically validate that your SQL injection defenses work correctly across your entire application.

StackHawk will test your .NET application for common SQL injection vulnerabilities, including:

  • String concatenation vulnerabilities: Testing endpoints that directly concatenate user input into SQL queries
  • ORM bypass scenarios: Finding cases where developers use unsafe ORM methods like FromSqlRaw() with unparameterized input

Instead of waiting for our AppSec team to notify us of an issue later in development, let’s use StackHawk to automatically identify this vulnerability for us. To do this, you’ll need to ensure you have a StackHawk account. If you need one, you can sign up for a trial account or log into an existing account.

If you’re logging into an existing StackHawk account, from the Applications screen, you’ll click Add Application.

Applications 52 findings dashboard

If you’re new to StackHawk, you’ll be automatically brought into the Add an App flow. On the Scanner screen, you’ll see the instructions for installing the StackHawk CLI. Since we will be running our testing locally, we will use this option. Once the hawk init command is executed successfully, click the Next button.

On the next screen, you will fill out an Application Name , Environment , and URL. Once filled out, click Next.

Since we will be testing a RESTful API, on the next page, we will choose our Application Type as “API”. Depending on what you have set up as a backend API, you’ll plug these details in. For example, if you have a REST API running, you would set the API Type to “REST / OpenAPI” and point to our OpenAPI Specification file by selecting the URL Path or File Path and adding the path to where your OpenAPI spec is located in the text box. Once complete, click Next.

Lastly, we will need to add a stackhawk.yml file to the root of our project. Once the file is added, copy the screen’s contents, paste them into the file, and save it. Lastly, we can click the Finish button.

In our root directory, we should see the stackhawk.yml file we’ve added:

Run HawkScan

Next, we can go ahead with testing our application. In a terminal pointing to the root of our project, we will run HawkScan using the following command:

hawk scan

After running the command, the tests should execute in the terminal.

Note that if you get an error similar to:

HawkScan Target Not Found Error: Unable to access https://localhost:4000. Check if the web server is listening on the specified port.

This means that your API is not running in HTTPS, and that is how HawkScan is trying to call the API. To fix this, either add HTTPS capabilities to your API or, more simply, change the host entry in your stackhawk.yml to use only “http”.

This will run tests against our API, including tests that can detect potential SQL injection vulnerabilities. Once the tests have run, we can begin to explore any findings that were discovered.

Explore The Initial Findings

Once the tests are complete, the terminal will contain some information about any vulnerabilities found. Below, we can see that StackHawk has found a few SQL injection vulnerabilities within my code that are present on multiple paths.

To explore this further, we will click on the test link at the bottom of the output. This will take us into the StackHawk platform to explore further.

After clicking on the link, we can now view the test results in a nicely formatted display. Next, we will click on the SQL Injection entry.

Within this entry, we can see an Overview and Resources that can help us with fixing this vulnerability, as well as the Request and Response that the API returned on the right side of the screen. Above this, you will also see a Validate button, which will display a cURL command with the exact HTTP request used to expose the vulnerability.

Understanding and Fixing SQL Injection Security Issues

When StackHawk identifies SQL Injection vulnerabilities, you’ll see detailed findings that indicate which paths are affected and provide potential remediation techniques (as shown in the image above). Using the techniques in this guide or the remediation advice provided by StackHawk for the vulnerability, you can then make the necessary adjustments to your code and configuration. Once fixed, ensure that you stop your servers and redeploy the latest code. Next, we can ensure that the fix implemented actually resolves our SQL injection issues.

Confirm the fix!

With the latest code deployed, let’s confirm the fix in StackHawk. To do this, we will click the “Rescan Findings” button in StackHawk.

Then, we will see a modal containing the “hawk rescan” command that includes the correct Scan ID. You’ll run this command in the same terminal where you ran the initial set of tests.

In the output, you will again see any vulnerabilities that were found during the scan. In this case, you’ll see that the SQL injection vulnerabilities are no longer showing. 

Clicking on the link at the bottom of the terminal output, you can confirm that the SQL injection vulnerabilities have now been added to the Fixed Findings from Previous Scan, confirming that the vulnerability has been successfully fixed and has passed any vulnerability tests.

With that, we’ve successfully remedied and retested our application to ensure its safety from potential SQL injection attacks.

Locking Down Your .NET App: Final Thoughts on Preventing SQL Injection

SQL injection vulnerabilities remain a critical security concern for .NET applications that interact with databases. While these attacks are well-understood and entirely preventable, they continue to affect applications due to unsafe coding practices and insufficient security testing.

The most effective defense against SQL injection is implementing parameterized queries consistently across your application. Combined with proper input validation and adherence to the principle of least privilege, these practices give the best defense against injection attacks.

Remember that securing your .NET application against SQL injection means ensuring your database interactions are safe while maintaining application functionality. Tools like StackHawk help automate this security validation, giving you confidence that your SQL injection defenses are both comprehensive and effective as your application evolves.

Want to ensure your .NET application is protected against SQL injection? Sign up for StackHawk today for a free 14-day trial to automatically test your application and detect potential vulnerabilities before they reach production.

FEATURED POSTS

Security Testing for the Modern Dev Team

See how StackHawk makes web application and API security part of software delivery.

Watch a Demo

Subscribe to Our Newsletter

Keep up with all of the hottest news from the Hawk’s nest.

"*" indicates required fields

More Hawksome Posts