The Security Samurai

Necessity is the plea for every infringement of human freedom. It is the argument of tyrants; it is the creed of slaves - William Pitt

My Links

Post Categories

Archives


Random Family Guy Quotes

Blog Stats

.Where I Work

General Blogs I Read

Security Blogs I Read

Useful Articles

All User Input is Dumb and/or Evil Until Proven Otherwise

In the last class I taught, the subject of user input validation came up and I think it’s important enough to share in my blog as well.  The courseware showed accepting all input as valid until proven otherwise (not in those words, but rather the pattern they showed for validating input).  As a matter of fact, this is how most developers deal with user input.  Think about it.  Most developers would code a statement where they accept a date of birth as:

obj.DOB = Convert.ToDate(txtDOB.Text); //Method A

instead of:

if(validator.IsDOB(txtDOB.Text)) //Method B, uses regular expression tests

{

obj.DOB = Convert.ToDate(txtDOB.Text);

}

In Method A, you are accepting the text in txtDOB to be valid unless it is proven not to be a date where as in Method B, we are checking to make sure it is not only a date, but a date of birth before we accept the data.  As developers, we focus on functionality rather than security.  We ignore the fact that a string does not equal a name, an integer does not equal an age, or a date does not equal a date of birth.

We need to get in the practice of defining all of the valid inputs we will accept and reject anything else.  I have been telling developers for years, that when it comes to user input, it is dumb and/or evil until proven otherwise.  Managers rarely like the sound of this statement, but it is important to adopt as a mindset.  All of your user input may be valid, your users are neither dumb nor evil, but you still treat their input that way, you still have to protect your app.

If you don’t adopt this mindset, you face a host of problems, such as dirty data, SQL Injection, Denial of Service (DoS), or even Cross Site Scripting (XXS) attacks.  Not all applications are susceptible to all of these attacks, like a XXS does not affect a WinForms app or a DoS attack is unrealistic against an intranet application, but that’s irrelevant.  Every application can be attacked somehow, and preventing invalid user input is the first step in protecting it against known and possibly future unknown attacks.

Another point to remember is that you should validate input everywhere in an application.  Generally you have sections for normal users, administrative users, and even utilities for IT personnel.  I once did a penetration test for a company, and the lead developer bet me that I would not be able to find a single flaw in the application.  After 2 solid days of hacking I had to say that I was impressed.  I could not find one single instance where input was not being validated, from text boxes to drop down list boxes to query string values normal users wouldn’t even see in blind redirects.  Everything was being checked.  That is, until I poked around and found the admin site.  I was able to log in with a SQL Injection attack and do anything I wanted to after that (whew, almost lost my record for breaking every app I’ve pen tested).  Administrators can be just as dumb and/or evil as regular users. 

There are downsides to performing aggressive input validation, namely performance and additional coding, but these are acceptable and can be managed.

Performance is a funny word that is thrown around way too much in our industry.  It’s true that if you were to compare a single valid user executing a request against an app which uses Method A, versus one that uses Method B, you would find that the first performs twice as well, however, executing an invalid request using Method A takes nearly 5 times the amount of resources as Method B.  Why?  Exceptions cause a huge impact on performance.  When an exception is thrown, it’s like throwing a monkey wrench into a well oiled machine.  Method A performs well under normal conditions, but fails miserably in the face of a DoS attack.

How so?  Say I wanted to create a DoS attack against a website.  I wouldn’t just have a bot network flood the servers with valid requests.  I would first try sending different inputs to the server to find a request with the longest average response time (the one that generates the most errors).  My goal is to force the server to do the most work using the least amount of my resources possible.  Once I find the right set of inputs to send, then I would have a bot network attack and hope it brings the server down.  DoS attacks can be poorly crafted by anyone, or they can be the work of a master hacker.
Method B ensures the scalability of an application.  Let’s say a valid request against Method A uses one performance point or 1 P (a mixture of CPU and memory utilization) and a request against Method B uses 2 P.  Also, an invalid request against Method A uses 5 P (that’s for one error, a request that generates multiple errors could use upwards of 20 to 30 P) and against Method B uses 2 P (no errors are thrown and it performs the same).  Under a normal user load of 10,000 users we would have the following:

% of Requests (Method A)

Cost Per Request

Total

99% Valid Requests

1P

9,900P

1% Invalid Requests

5P

500P

 

Total:

10,400P

 

% of Requests (Method B)

Cost Per Request

Total

99% Valid Requests

2P

19,800P

1% Invalid Requests

2P

200P

 

Total:

20,000P

Under attack, the ratio of valid to invalid request would change and affect performance:

% of Requests (Method A)

Cost Per Request

Total

50% Valid Requests

1P

5,000P

50% Invalid Requests

5P

25,000P

 

Total:

30,000P

 

% of Requests (Method B)

Cost Per Request

Total

50% Valid Requests

2P

10,000P

50% Invalid Requests

2P

10,000P

 

Total:

20,000P

A system designed to withstand 10,000 P would have a hard time handling 30,000 P.  It’s better (and easier) to buy enough hardware for an application that is scalable and will perform predictably rather than one that won’t.

The second problem is on the coding side, writing the input validations.  It can be as easy as you make it or extremely inconsistent and not implemented everywhere.  Normally I will build some sort of regular expression utility in a library.  For every type of input that is accepted by the app, there would be a correlating IsXxx(string) method which returns true or false.  Each method would use a custom regular expression based off of the rules defined for that application.  While different applications accept similar types of input, each one has its own specific rules for valid values (i.e. name.name@url.com vs. name@url.com) and is why you can’t simply copy and paste it from app to app. 

I would like to create a wizard based regex utility that would allow you to define all the types of input and associated rules (i.e. a name with up to 50 characters allowing only A-Z, a-z, ‘, and “ “, a Visa and Amex credit card number, or a date between x and y).  After a user defines the input, the wizard would determine the regex pattern and compile them into a library (regex’s need to be compiled if they are to be run in a server environment for performance reasons).  It would need to be able to save state so it could be run again in the future to modify a certain regex pattern.  I can search/modify/make a regex pattern given a set of rules, but this is a little over my head.  If anyone out there knows someone who is a regex guru that could create the regex patterns dynamically based off of options a user selects, send them to me.  I have the whole thing worked out in my head and am going to start working on it in the mean time.

Until then, you can use www.regexlib.com to find any expressions you may need and make your own utility.

 

posted on Friday, July 01, 2005 12:17 AM