Best practices: Secure ASP.NET Web with DevExpress: A1- Injection

Don Wibier's Blog
06 October 2014

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:

clip_image001

But what if we specify:

Default.aspx?q=Crank ' union all select 0,'',TABLE_SCHEMA%2B'.'%2BTABLE_NAME from INFORMATION_SCHEMA.TABLES –

clip_image002

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.

2 comment(s)
Glen Harvy
Glen Harvy

I like warm fuzzies :-)

Thanks for this post as it helps take the mystery out of issues that should be known to all serious programmers.

6 October, 2014
Irfan Ali QAU
Irfan Ali QAU

Very nice. Thanks

4 December, 2014

Please login or register to post comments.