Trust No One

One of the central tenets of web application programming is: never trust the user's input. When a user submits a form, every input that is to be used to complete the request must be validated. No assumptions can be made as to the type, range or existence of a form value. Everything is suspect and each value must be checked.

As a developer on the server-side, you cannot assume the type of client application the user is running, nor can you assume the capabilities of the client application. For instance, if you require that users of your web application use Internet Explorer with Javascript enabled, you cannot assume that any form submissions that you receive on the server came from someone running Internet Explorer with Javascript available. Even if you put in elaborate precautions and detection measures to make sure your site is only responding to a particular browser and capabilities, you can never be 100 percent certain that a form submission actually came from said browser with said capabilities. The potential for deception or circumvention is too great and spectacularly simple. Nothing prevents a user from using another browser to make a form submission, modifying a page locally and submitting it to the server, or even manually initiating a form submission using a telnet client connected to your web server port. It can be done and, surprisingly, with little effort.

Client-side validation beware!

One of the scariest (and I am sure it exists more often than I care to know about) is trusting the validation of user input to client-side Javascript. From the server-side perspective, you can never assume that the Javascript validation was performed and performed correctly. Any validations performed client-side must be repeated on the server-side. Trusting the submitted data is a surefire way to have your web application compromised. Browsers provide the option to disable Javascript and if a visitor to your site happens to have Javascript disabled, you can be sure that none of your client-side validations occurred.

This brings up an interesting point: why bother with Javascript validation? If Javascript validation cannot be relied upon and must be duplicated on the server-side, there can be little benefit derived from doing so. It results in maintaining validation in two different places and they must always be in-sync. If validation rules are added or changed, it must be changed in the Javascript and in the server-side code. This makes code maintenance more complicated. The only benefit to use Javascript validation is to make the user experience pleasant. Immediately informing users of invalid input before submitting a form is more responsive. It also saves a request-response round trip and lightens the load on the server by pre-empting bad submissions. This "benefit" must be weighed against the fact that there will be added complexity in keeping the client-side and server-side validations coherent.

Leave no stone unturned

Every form element needs to be validated -- not just text input fields where the user is allowed to enter any freeform value. Select-box elements and radio buttons need to be validated even if the values are assigned, for the simple reason that the values can be tampered and alternate values can be injected. How can this be done? As I alluded to earlier, anybody can save your web page form locally, edit the page, load the local page into a browser, and submit the modified form to your application.

Think it is too complicated to do? Here is an example to demonstrate the efficacy of tampering with an HTML form. You will find on the following page a simple HTML form that contains a select-box where you can choose from a pre-defined set of values. When you submit the form, the resulting page will display to you the option that you selected. As the form only contains a select-box with fixed values, an ignorant developer might assume that the value received can only be one of the available selections. So lets go about tampering with the page and injecting our own values to be submitted.

  1. Load the page into your browser.
  2. Save the page to your local hard drive. [Save page as...]
  3. Open the saved file in a text editor.
  4. Search for one of the available select options and modify the value attribute to some random string value. Preferably, not a value already used.
  5. Save the file
  6. Open the local file into your web browser
  7. Select in the drop-down box the option that you modified the value for, and submit the form.

In the result page, you will see the tampered value that you inserted. Sure, the example is contrived and simplistic, but the point should be clear: you can never trust the source of the submission.

In the world of web application programming, trust does not exist.

[[Top of page]]