Why client-side validation is a lie

May 26, 2007

no comments

You probably heard it a million times. It is one of the golden rules of web-development. Do not rely solely on client-side validation to ensure you get the data that you expect from the browser. Anyone can send you a crafted request that bypasses your script validation. Always validate on the server as well. And yet, I see a lot of commercial sites that ignore this rule, and it is easy as hell to break their logic. In fact, with the following simple steps I will show, you can bypass any javascript-only validation.

Consider the following TestValidation.htm page:

1 <html > 2 <head> 3 <title>Validation Lies To You</title> 4 <script> 5 var valid;
6 function validate() {
7 valid = document.getElementById('Text').value != "";
8 if (!valid)
9 alert('Not Valid!');
10 return valid;
11 }
12 </script> 13 </head> 14 <body> 15 <form method="post" action="save.aspx" onsubmit="return validate();"> 16 <input id="Text" type="text" /> 17 <input type="submit"/>
18 </form> 19 </body> 20 </html>

This html page contains a form, a text box and a button. The validate function checks if the form is valid (in this case that the text box contains a value, but it can do any other validation as well). If it is valid, the form will submit to save.aspx, if it is not – an error message is displayed.

In order to bypass this validation we don’t have to craft an http-request or play with the script options of our browser. What we need to do is this:

  • Install Firebug. This is a great add-on to Firefox that can help you debug web-sites and javascript easily. And also bypass client side validation.
  • Point Firefox to our TestValidation.htm. Hit submit. Err, javascript alert. Can’t submit. What can we do?
  • Open the Firebug console (via the Tools->Firebug menu or the Firebug icon on the status bar).
  • Go to the script tab in the Firebug console and place a breakpoint on line 8 in the code (the "if" statement).
  • Now hit the submit button, the breakpoint will hit and the page will halt.

This is where we are:

  • We want to change the value for the "valid" variable. We go to the console tab (which is somewhat like the VS debugger "immediate" window) and enter "valid=true".
  • Now we go back to the script tab and hit F5. The form posts like a charm.

Now you could say I cheated a little by making "valid" a global variable, and indeed I couldn’t find in Firebug a way to change the value of a local variable of a function (the console seems to affect only global DOM elements, unlike the VS debugger "immediate" window). But even if it were a local variable I could write in Firebug the following (before clicking the button):

document.forms[0].onsubmit = function(){return true;}

Or simply:

document.forms[0].submit()

The form would have submitted perfectly in both cases, ignoring the client validation.

So we have arrived at the following conclusions:

  1. Client-side validation is not security. Always validate on the server side as well. ASP.NET’s default validators do this for you, but if you use CustomValidator remember to handle its Server_Validate event.
  2. Firebug is an awesome tool – I wish I had an equivalent for IE (for the meantime I’ll have to settle for IE Dev Toolbar).

Happy coding!

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*