I’ve had a lot of experience in dealing with writing secure ASP.NET websites. I’ve created a custom CMS framework using DevExpress ASP.NET and been through several security audits with this project. I’d like to share my experience with you in using best practices to make your websites secure. In this series of blog posts I’ll write about security so you can take your advantage of it before you start to code.
Open Web Application Security Project
OWASP is one of the most well-known organizations which focuses on improving security of software. They have published a checklist with common design errors and issues. The OWASP Top Ten represents a broad consensus about what the most critical web application security flaws are.
Let’s see what this type of attack is about and how to fix it:
A1 - Injection
This kind of attack allows a hacker to send custom server-side commands to your web-server by manipulating the url or it’s query strings, or manipulate data entered in forms which are being posted back to the server.
Let me give you a small example on how this works on the AdventureWorks database:
Suppose we want to display a filtered grid with products, where the filter is specified by a query string parameter:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
using (SqlConnection conn = new SqlConnection(
ConfigurationManager.ConnectionStrings["AdventureWorks2012ConnectionString"].ConnectionString))
{
string sqlText = String.Format(@"SELECT ProductID, ProductNumber, Name
FROM [Production].[Product]
WHERE Name LIKE '%{0}%'",
Request.QueryString["q"]);
using (SqlCommand cmd = new SqlCommand(sqlText, conn))
{
conn.Open();
SqlDataReader rd = cmd.ExecuteReader();
GridView1.DataSource = rd;
GridView1.DataBind();
}
}
}
}
This al looks pretty nice and when we specify a url like: Default.aspx?q=Crank, the result will be like:

But what if we specify:
Default.aspx?q=Crank ' union all select 0,'',TABLE_SCHEMA%2B'.'%2BTABLE_NAME from INFORMATION_SCHEMA.TABLES –

Wow! Look at that! It displays all tables in the database and that is how an injection attack works.
Because the constructed SQL is being generated runtime with no checking at all, I was able to change the entire sql statement by injecting some obscure code and get sensitive information about the system for subsequent hacking attempts.
The statement was altered from:
SELECT ProductID, ProductNumber, Name
FROM [Production].[Product]
WHERE Name like '%Crank%'
To:
SELECT ProductID, ProductNumber, Name FROM [Production].[Product]
WHERE Name like '%Crank' union all
select 0, '', TABLE_SCHEMA + '.' + TABLE_NAME from INFORMATION_SCHEMA.TABLES --%'
Perhaps you’re thinking: “Yeah but I have a database with different fields, and you don’t know the amount of fields I am selecting for the union etc.”
Those thoughts are really of no concern for a hacker. He can give it a shot by spending 30 minutes every day for a week and he will sort it out.
Remember: Hacking is not a quick job but it requires time and patience.
So can this be fixed ?
Sure, this can be fixed in several ways:
Weak solution: Remove quotes
We could strip out all single quotes by calling:
Request.QueryString["q"].Replace("'", "")
But this could cause culture related issues.
Better solution: Parameterized Queries
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
using (SqlConnection conn = new SqlConnection(
ConfigurationManager.ConnectionStrings["AdventureWorks2012ConnectionString"].ConnectionString))
{
string sqlText = "SELECT ProductID, ProductNumber, Name
FROM [Production].[Product]
WHERE Name LIKE @SearchText";
using (SqlCommand cmd = new SqlCommand(sqlText, conn))
{
cmd.Parameters.Add(new SqlParameter("@SearchText",
String.Format("%{0}%",
Request.QueryString["q"])));
conn.Open();
SqlDataReader rd = cmd.ExecuteReader();
GridView1.DataSource = rd;
GridView1.DataBind();
}
}
}
}
If you would try the same trick again, you will see that nothing is found since my attempt with the union is now part of the LIKE parameter.
An additional bonus is that you will gain a bit of performance since MS-SQL Server is now capable of caching the SQL Statement internally, so it doesn’t need to parse your statement with every request.
Alternative better solution: Use an ORM tool
Another way of avoiding SQL injection is by using some ORM (Object Relational Mapping) tool like the Entity Frame Work or eXpress Persistent Objects.
Because you are not working with SQL directly the ORM tool will construct the proper queries with parameters for you.
DevExpress is Secure
DevExpress takes ASP.NET security as a top priority. We constantly test our tools and if by chance a flaw appears then we’ll notify you immediately on a fix/workaround/etc.
Leave a comment below with your thoughts on ASP.NET security.
Free DevExpress Products – Get Your Copy Today
The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the
DevExpress Support Center at your convenience. We’ll be happy to follow-up.