Wednesday, July 28, 2010

What is client side input validation and implementing it with javascript……………………………

Last time I discussed a situation where client side input validation would have assisted in preserving the security of a web application. I discussed how and what happen that revealed several details to me by entering an extra digit into a input field. This information could have easily allowed me to own the web application, and possibility the server! I want to state when securing a web application you must use defense-in-depthstrategy. When writing web applications, using client side input validation is the first of many layers in your defense strategy.

To recap client side input validation is the process of testing input on the client to ensure the user entered in the expected value types (numbers, letters, characters, or a combination of these) in a field before sending the data to the server.

There are two methods used to perform input validation, whitelisting or blacklisting. Whitelisting is defining what is expected and denying everything else. Blacklisting is denying certain values and allowing everything else.

Which method of input validation is better? In a perfect world whitelisting is the preferred method, but this is not a perfect world. With blacklisting the issue of encoding is encountered. To see blacklisting encoding issue in action, lets’ use the dash( - ) as an example.

You create a blacklist in your application that denies input with the dash ( - ) in the Zip Code input field because it is often used with SQL injection attacks such as ‘ or 1=1--. What happens when an attacker enters in ‘ or 1=10x2A0x2A? If the blacklist does not look for various encoding schemes the attacker can bypass client side input validation routines. So to resolve this issue you can add 0x2A (Hex), etc., until you get all possible encoding schemes covered, but this is an administrative nightmare for all but the simplest blacklist.

Using a whitelist with only known good values, in this example all digits and the problem is solved. The problem is solved until an input field, such as a Zip Code input that uses the extended Zip Code+4, requires the - in the input field. This is where defense-in-depth comes into play and sanitized user input is used to solve the problem of legitimate use of otherwise bad characters, but that is a subject of another article. Lets’ see an example of client side input validation in action.

Our example application uses ask the user for their Zip Code. Zip Code fields are great to use as examples for client side input validation. The ZipCode application consists of the input form where the user enters in their zip code and the php application returns the Zip Code the user inputted into the form. The input form name is zip.html and consists of the following code, where the user enters in their Zip Code into the zip input field:

<-html->
<-title->Please enter in your zip code<-/title->
<-br->
<-form method="POST" name= “zipform” action="zip.php"->
<-center->Enter in your zip code (Only 5 digits please):<-input type=text name="zip"->
<-br->
<-input type="submit" value="Enter Zip Code"-><-/center->
<-/form->
<-/html->

Once the user clicks on the ‘Enter Zip Code’ button, the form is submitted to the server and processed by the zip.php application which is the .

<-?php print "You entered in "; print $_POST['zip']; print " as your zip code"; ?->

Once processed the php code returns this output page:

You entered in 12345 as your zip code

Now if the user enters in 123456 the application returns 123456 because no input validation is performed. In the US, zip codes are 5 digits and entering in 6 digits is an invalid zip code and should be rejected. If we use the code from above it is possible to submit bad data to the application, which can lead to compromise of the application and possibly the server.

So how do we prevent a user from either accidently or intentionally entering in 123456 into the zip code field? The quickest way is to use the MAXLENGTH HTML attribute. All that is required is adding the MAXLENGTH attribute to the input text attributes. Here is an example of using MAXLENGTH added to the HTML from above:

<-center->Enter in your zip code (Only 5 digits please):<-input type=text name="zip" maxlength=5->

Now when a user tries to enter in 123456 in to Zip Code input field the form will only allow them to enter in 12345. Great, an invalid zip code can’t be entered into the application. So MAXLENGTH can be used to limit the length of input into a field.

But what happens when a user enters in ABCDE in the zip code field? The application will return the following:

You entered in ABCDE as your zip code

This is valid input because its 5 characters long, but it is alphanumeric and not numbers and the application accepts’ the input because it meets the MAXLENGTH attribute. So now how do we validate that only numbers are entered into the Zip Code field and no other values?

To validate we must use a script to check the length and type of character entered in the Zip Code field. First the form attribute must be modified to run the javascript. To get the javascript code to run we modify the form attribute using the following:

<-form method=POST name="zipform" onsubmit="return validateme()" action=zip.php->
<-center>Enter in your zip code (Only 5 digits please):<-input type=text name="zip"->
<-br->
<-input type="submit" value="Enter Zip Code"-><-/center->
<-/form->

The onsubmit is a scripting event that performs error checking, if error checking passes the input is then submitted to be processed. However if the error checking fails the event is not submitted, and usually some form of failure notification is presented to the user.

Because the checks are being performed client side the code must be added to the HTML document. Typically, this type of event is placed in the head tag in the HTML document. First the head tag must be added, than the scripting language must be declared. Here is the added code to the HTML document:

<-head->
<-script language=JavaScript->

Next the function to be used, named validateme, must be declared. Because multiple checks are going to be performed the variable zv is declared, which contains the zip code input field from the form.

function validateme()
{
var zv = document.zipform.zip.value;

The first input validation checks the length of input. In the case of the input not consisting of 5 characters the alert message of “Please enter in 5 characters” is sent back to the user. If the input is 5 characters the next validation check is performed. The code for the first validation check is below:

if (zv.length != 5)
{
alert("Please enter in 5 characters");
return false;
}

The next check is to see if the value entered is a valid Zip Code. To perform this check regular expressions or regex will be used. The check will match the regex of /\d\d\d\d\d\$/ to the zip code. If the input is 5 digits the validation is considered true and passed to zip.php for processing. If the zip code is not 5 digits the message "The Zip Code field does not contain 5 digits." is returned to the user.

if (zv.match(/\d\d\d\d\d$/))
{
return true
}
else
{
alert("The Zip Code field does not contain 5 digits.");
return false;
}
}

Finally to close out the script section and the head section of the HTML document these last two HTML tags are added:

<-/script->
<-/head->

This is a very simplistic example of client side input validation, but it attempts to expain and show how to implement it. Please note that the dash added into the HTML Comments is for displaying the HTML code.

With client side input validation, next time I will discuss a few ways to bypass client side input validation during a web application pen test.

Wednesday, July 14, 2010

What can happen if you don’t perform client side input validation……

The other day I was visiting a rewards website that required me to enter in my 9 digit member number (thank god it was not my SSN) printed on a little wallet card. I pull out the wallet card and entered in my member number and hit enter, fully expecting to see a web page telling me how many reward points I had earned.

Immediately an error message was returned stating an error occurred. Getting the error message itself didn’t shock me, it was the information I gathered from the error message

From the returned error message I was able to determine the server operating system web server, and scripting engine, and a link to click on for the stack trace information. I click the link, and detailed exception information is displayed. All I can say is HOLY CRAP Really?

To determine what went wrong I hit the back button on my web browser. Reviewing the page I looked at my rewards number and saw that I accidently entered in 10 digits instead of 9 digits.

From one error message I was able to determine three issues with the website, lack of input validation, incorrect error handling, and information disclosure. While all of these issues can be detrimental to the security of an application I want to specifically discuss input validation.

There are two types of input validation, client and server side. These validation types should be used in conjunction to complement each other, and should not be used by themselves!

What is client side input validation? Simply put client side input validation is the process of testing input on the client to ensure the user entered in the expected value types (digits, numbers, characters, or a combination of these) in a field before sending the data to the server.

The two primary benefits with client side input validation are client side error checking, and error location identification. Client side error checking is used to look at values entered into a field and see if those values are considered valid (i.e. help identify typo’s in the field). If the values are not considered valid an error message should be generated identifying which field was not valid.

Why not rely on client side input validation for security? Because bypassing client side input validation is trivial, real trivial. So any input validation performed client side, must be performed server side as well.

Using the rewards website example, had the website performed client side input validation on the member number field, I wouldn’t have seen the error message that lead to the discovery of three issues with the website. If I were performing a web application security assessment for this web site, I would venture to guess that owning the application would take very little effort.

So client side input validation by itself doesn’t secure an application, but when used in conjunction with other methods it can increase the security of a website, ala Defense-in-Depth. In my next article I will discuss how to implement client side input validation, with an article to follow on how to bypass client side input validation!
 
Site Meter