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.

No comments:

Post a Comment

 
Site Meter