Showing posts with label input validation. Show all posts
Showing posts with label input validation. Show all posts

Tuesday, August 3, 2010

Bypassing Client Side input validation…..

Last post I discussed how to implement client side input validation, and previously have discussed whey it should be used. Today I will discuss the best part of client side input validation, how easy it is to bypass!

This post hope to explain how easy bypassing client side input validation really is. For demonstration purposes the code examples from the previous post will be used to demonstrate three very easy attacks that bypass client side validation. To recap here is the HTML code for zip.html, the form to enter in a zip code.

<-html->
<-head->
<-title->Please enter in your zip code<-/title->
<-script language=JavaScript->
function validateme()
{
var zv = document.zipform.zip.value;
if (zv.length != 5)
{
alert("Please enter in 5 characters");
return false;
}
if (zv.match(/\d\d\d\d\d$/))
{
return true
}
else
{
alert("The Zip Code field does not contain 5 digits.");
return false;
}
}
<-/script->
<-/head->
<-br->
<-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" maxlength=5->
<-br->
<-input type="submit" value="Enter Zip Code"-><-/center->
<-/form->
<-/html->

The first and simplest attack to bypass client side validation, drum roll please…., is to disable JavaScript in the browser. That’s it, a pretty tough attack since you must restart the browser to take effect. A variation of this attack is use a browser like Firefox that supports extension with the NoScript extension installed and forbid the host from running scripts.

The second method requires a very special and 3l1+3(elite in l33t speak) tool called a text editor such as gedit or notepad. In the sample code zip.html, validation must be bypassed in two places, the HTML MAXLENGTH Attribute and the validateme function. To begin performing this attack, open up zip.html in a web browser of your choice and save the page to the local system.

The first thing to deal with is submitting the form back to the original website, in this example www.badwebapp.com. If the page is using relative paths as seen in the example code below, the form action properties must be changed.

<-form method="POST" name= “zipform” action="zip.php"->

To send form back to badwebapp.com change the action property to www.badwebapp.com, as seen in this code example:

<-form method="POST" name= “zipform” action="http://www.badwebapp.com/zip.php"->

If this is not change the form will attempt to post the data to the local system and a 404 error will be returned to the browser.

With the form ready to be processed on the original website the first thing to deal with is the HTML MAXLENGTH Attribute. Open up the file zip.html go to this line:

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

Delete the MAXLENGTH Attribute, and the first validation input is ready to be bypassed. Save the file to the local system, than open the file in a web browser. It is now possible to enter in more than 5 digits in the input field, however a warning box from the validateme function will indicate that more than 5 digits was entered.

There are three options to bypass the JavaScript validateme function. The first is to use HTML comment tags (< ! - - What is to be commented out goes here - - >, change the code itself, or remove the onsubmit property from the form properties as seen in this example:

<-form method="POST" name= “zipform” onsubmit=”return validateme()” action="zip.php"->

Any of the three methods will be sufficient enough to bypass the validatme function. After completing the changes to the file, save it to the local system. Open zip.html in a web browser, and enter in any information such as ABCDE12345 and submit the form for processing by the web server. Since this web server performs no server side input validation the following message will be returned:

Congratulations! Your zip code is ABCDE12345 Thanks!

Changing the code can be a lot of work, especially in a web application that performs multiple client side input validation checks. What about changing data after the validation, but before its submitted to the webserver? That is what is done in the third attack.

To perform this attack a web proxy intercepting application such as OWASP WebScarab is used.

After installing WebScarab, fire it up and configure it to intercept request. When running WebScarab in the Lite interface just click on the Intercept tab and check the Intercept Request box. Next open up your browser of choice and configure it to use 127.0.0.1:8008 as the proxy server.

Now enter in 5 digits, which is the valid length for a zip code, and click on Enter Zip code button. As soon as this occurs the following screen shot will popup:



Now change the variable zip value to ABCDE12345 and click on the Accept Changes button. Once again you are presented with the following message:

Congratulations! Your zip code is ABCDE12345 Thanks!

As you can see client side input validation is great to detect typos’ and data entry mistakes, but does not increase the security of an application.

Much like a border router, adding client side input validation to a web application can be used as the first layer of defense in the security of a web application. Just remember how easy client side validation can be bypassed as seen in this example, and should NEVER be trusted!

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