adOpenStatic Logo
Ken's Blog
Contact Ken
Copyright 2000 -

A methodology for validating user input
One of the perennial problems that I see when examining ASP code is a failure to adequetely protect databases and applications from invalid user input. Often there is no handling. Sometimes there may be some client-side javascript. And only in the professionally developed applications is there some graceful handing of code failure built in.

What we'll be examining here is a system that allows you to:

  • Quickly develop client-side validation
  • Quickly develop server-side validation
  • Handle invalid user input

I'll be the first to admit that isn't the only way that this whole thing can be done, and I welcome any comments or suggestions on how to improve the whole process, or even wholesale alternatives.

Why client-side validation is not sufficient
An important point to realise here is that client-side scripting validation is only for the benefit of the user. It is not to be used to protect your application or database from invalid data.

I've heard argument that it is not necessary to provide server-side validation as it "wastes" CPU cycles and further that users that disable client-side scripting and then submit invalid data are only doing themselves a dis-service as they will be presented with a nasty ADODB or VBScript runtime error.

Let me make it clear that nothing could be futher from the truth. There are a number of excellent articles on the WWW that describe "cross-site scripting vulnerabilities" and "SQL Injection Attacks". The consequences of either of these attacks can be quite significant.

A simple example of SQL Injection
Many websites have login pages whereby members or administrators can access restricted content. The login form requests the user enter a username and password, which is then concatenated in an ASP page to form an SQL SELECT query. The results of this query are used to determine if the user has been authenticated or not.

strSQL = _
   "SELECT Status " & _
   "FROM Users " & _
   "WHERE UserName = '" & strUserName & "' " & _
   "AND UserPassword = '" & strUserPassword & "'"

A system that fails to adequately validate user input leaves itself vulnerable. For example if the target machine is using SQL Server as a backend database then the attacker could embed -- into their input commenting out part of your SQL string.

As an example, the user could enter: Admin' -- into your Username text box. Your resulting SQL statement would look like:

FROM Users
WHERE UserName = 'Admin' --' AND UserPassword = ''

Since everything following the -- is treated as a comment by SQL Server part of your SQL statement has been excised. 0 The user is automatically authenticated provided they can find a valid username in the database. This can also be achieved via SQL Injection attacks (by injecting SELECT statements into your code.

A simple example of Cross Site Scripting
Suppose you have a website that allows visitors to submit their favourite links. You display the most recent submissions on your homepage to other visitors. Or suppose you have a system for people to signup for a newsletter - you review the email addresses submitted via an administration page. Or...basically you have any page that accepts user input and that user input is displayed on any device that renders HTML (ie another webpage, or even an email program that renders HTML).

Suppose, instead of entering something valid, the user enters the following:

<script language="javascript" type="text/javascript">alert("Ha Ha Ha");</script>

The person that next views this data is going to see a javascript alert box, not a URL, or email address. What's worse, the above could be VBScript instead. Granted, it'll only work in IE, Outlook and Outlook Express, but that's still a substantial number of users, and VBScript/VBA allows all sorts of functionality that browser based javascript can not accomplish.

More Information
The following articles discuss the vulnerabilities above in more detail

Developing Solutions
There is no such thing as the completely secure system. Security is all about making it uneconomic for the attacker to spend time or money attacking your system. As such, the development of any defensive mechanism involves evaluating the cost to your organisation of a worst possible outcome (eg complete loss of data, loss of confidence in your systems by your business partners etc). This cost should be used in determining what effort should be put into defending your system.

In addition to there being no single correct "level" of security, there is no single correct "method" of securing your system. Here we are talking about the concept of "security in depth" - the idea that multiple methods should be employed to guard your systems against attack. In terms of web applications we would be talking about using stored procedures as much as possible, allowing the anonymous internet user account minimal priveleges in our database, validating user input and having our SQL Server inaccessible directly from the internet.

Now that we have dealt with that topic, the following series is divided into the following:

Onto Overall Structure

Back to Code Listing