Data Sanitization - Reducing Security Holes in an ASP Web SiteBy Craig Atkins
ASP is a great Web development technology that allows for rapid development of data-driven Web sites. However, problems can arise, however, when developers "go live" with code that contains potential security holes due to rushing out poor code, or not knowing the exploits that exist. In this article we will examine two common security holes that can be exploited by knowledgeable hackers: SQL Injection and Cross Site Scripting.
It is surprising (and alarming) how many production Web applications/Web sites contain some major security holes based around these exploits. Furthermore, the amount of source code published on "educational" ASP sites (such as 4Guys, even) that suffers from these two common security pitfalls is shocking.
What is SQL Injection?
For data-driven Web sites, commonly the database queries issued are based, in part, on user input. For example, if your site has user accounts, requiring users to log in with the username and password, on the login page you likely have the user input their credentials, which you then use in a SQL statement to see if the user's supplied username and password match up. SQL Injection is a method of exploiting a Web application that takes a clients input data (such as a user's entered username and password) and uses it to form part of an SQL statement that is passed directly to a database.
An SQL Injection attack can be used for numerous nasty purposes depending on the hacker's skills and patience, such as logging into a website, stealing credit card details, deleting entire databases, or in some cases (where SQL server is used, and certain installation conditions are met) gaining access to the Web server's file system. Any SQL statement that uses unsanitized user input data is potentially vulnerable to an SQL Injection attack.
For example, imagine that we have a login page as previously described that accepts the user's username
and password as input, and then checks the database to see if the credentials are correct. The VBScript
code for this may look as follows (the below script shows the code that authenticates the user - it
assumes that it is being called from a form where the TextBox for the user's username was give the
If the user enters in the login page a username/password pair of "Craig" and "foobar", then the SQL query:
SELECT * FROM tblUSERS WHERE UserName = 'Craig' AND Password = 'foobar'
will be executed. If there is such a user, then the Recordset
rs will contain a row with
information from the correct user from the
tblUSERS database table (assuming there aren't
multiple users with the same username/password). Great! That seems to work fine, and is nice and
simple. But, imagine for a moment, what would happen if the user enters his username or password as:
' OR '' = '
When a user provides such a username the following SQL query will be issued:
SELECT * FROM tblUSERS WHERE UserName = '' OR '' = '' AND Password = 'password entered'
This SQL statement will return all matching records from
tblUSERS. Why? Because the
query has now been altered to disregard the users input, and compare nothing (
nothing, which will always equal true. (Other variations on this might be using
1 != 0 or other "always true" boolean expressions.)
Our friendly hacker has just gained access to the "secure" area of our Web application... not good is it?
How do we Protect Against SQL Injection?
The best way to protect against SQL Injection is to sanitize the user's input data before placing it within a SQL query. Sanitizing data is the act of stripping out any characters that we don't need from the data we are supplied. Returning to our username/password example, the username field, say, should only contain alphanumeric characters (and maybe spaces, underscores, etc. depending on your configuration). Importantly, username values (and password values, for that matter) should not contain apostrophes. Sanitizing user input, then, ensures that these user inputs contain only the valid characters. By requiring that the username and password being passed to the database does not contain any invalid characters, we can protect ourselves against a SQL Injection attack.
The easiest way to sanitize your data is to simply replace all apostrophes with two consecutive apostrophes.
In fact, in the 4Guys article Protecting Yourself from SQL Injection Attacks
by Ross Overstreet, Ross shows how to use the VBScript
Replace function to perform this task.
Personally, I prefer to use regular expressions to strip any characters outside of the predefined
"legal" characters. (As discussed in the last paragraph, such legal characters for a username may be
alphanumeric characters and underscores.)
|What are Regular Expressions?|
|Regular expressions are a powerful set of tools designed for string parsing and pattern matching. To learn more about regular expressions, start with Scott Mitchell's An Introduction To Regular Expressions.|
Therefore, in order to protect our earlier ASP page example from a SQL Injection attack we will need to add the following code to clean our username so it only contains alphanumeric characters.
With the above code in place, if the user entered his username as
the regular expression would strip the extraneous characters and set the variable
username to the value
"username". We should use this method of sanitizing
data on all of the code that comes from a users browser (such as the password entered by the user).
In fact, data sanitization should be applied to data from form fields, hidden fields, disabled fields
and cookies as well. Never assume that client side validation is working correctly, as hackers can
circumvent this, and never assume that cookies cannot be edited, as they can, so their data should
always be treated as unclean.
Now that we've examined the SQL Injection attack, let's turn our attention to the Cross Site Scripting attack, which, while different, is related to the SQL Injection attack in that its vulnerability stems from unsanitized data. We'll examine the Cross Site Scripting security hole in Part 2.