Web Application Security

Sometimes Input MUST be Validated Client-Side: o_O

You read that right. The title violates one of the most fundamental rules of Web application security, which is that input must be validated server-side. A vital rule since website attacks originate from the client, such as a web browser, and the data it sends cannot be trusted. Attacks like Cross-Site Scripting (XSS), SQL Injection, and many others can be thwarted by adhering to a simple rule: don’t trust client-side data. However, the technology design of Google ChromeOS, and to the same extent Apple iOS, has inverted the well-established model of where Web applications are deployed, and simultaneously changed where input-validation must typically take place.

Garden variety Web applications, the things written in Ruby/PHP/Java/.Net/Perl are deployed and executed on Web servers — that is to say, server-side. In Chrome and ChromeOS, users download special applications and extensions written in HTML/JavaScript from the “Chrome web store” where they are installed and executed client-side — in their Web browser. This is an important difference to understand as where an application gets its input, and where its executed matters a great deal to security. An excellent example of this came to light this summer with the “Hacking Google Chrome OS” research conducted by Matt Johansen and Kyle Osborn.

Let’s assume a Chrome/ChromeOS user installs an application from the web store, like an RSS reader, which reads in data from different “untrusted” URLs all across the Web. The RSS application parses, organizes, sometimes even executes, the XML feed data, and finally displays the list of stories to the user. All this data processing takes place client-side, within the browser walls, NOT on any server. In fact, there is no “server” in this Web application deployment model.

Next let’s assume one of the aforementioned RSS data sources suddenly contains malicious content, an XSS payload for example, where it executes in Web browser context when displayed. Depending on the security permissions that the application set for itself, may of which are wide open, XSS payloads can do quite a bit of damage — even from within the browser. As demonstrated by Matt and Kyle, all of a user’s email, contacts, and saved documents is potentially at risk. Their machine can be used to conduct high speed scans of their intranet. Messages from their Google Voice account can also be spoofed. The list goes on and the security sandbox doesn’t provide any protection. Similar attacks can be carried out through applications such as email readers, instant messagers, and so on. In fact, this type of XSS vulnerability is fairly common among Google web store applications and has also been shown to affect Apple iOS applications, like Skype mobile, in a very similar way.

The critical point is that, since the Chrome/ChromeOS (and similar applications) execute client-side and receive untrusted data from servers as opposed to the other way around, the only safe place to perform input-validation is actually client-side! Strange as that may be.

Unfortunately, if you are a user of either platform, there is not much you can do to protect yourself against applications that are vulnerable. If you are a security conscious developer, the guidance for input validation hasn’t changed. Ensure incoming data, wherever is originates from, is what it’s expected to be before using it. Look for correct character sets, data being not too short or too long, proper formatting, etc. Maybe we should update the rule to “All input must be validated.” Done.

  • Sripathi Krishnan

    In a way, client side validation has been the norm when parsing JSON. Most libraries fall back to eval() to parse json – so it becomes important to first validate that the string is just data and not some arbitrary code. So, the libraries test the string using some nifty regexes – which it makes it “client side validation of input that comes from the server”.

  • http://blog.astyran.sg Herman Stevens

    The rule should indeed be made more clear for developers. Similar problem is that companies consider “input” (a read) from their database as trusted, while in many cases it is not, unless one can be absolutely sure that all applications that use that database perform input validation. A nice example: a colleague of mine went to the counter of a major bank, and made a payment to another customer, with as reason for payment the classical script-alert-script combination. This was input in the back-office application by the bank clerk without questions asked. Of course the script was executed when that customer displayed the reason for payment in the internet banking application. Doing the same – payment to another person with malicious script – through the internet banking interface failed (that application did perform input validation). In this example output encoding would also have prevented the attack, but in modern applications a lot more can go wrong then a simple XSS attack in the browser.

    There is yet another reason for client side input validation even if the same is done server-side: if input arrives at the server-side and catched by the validation routine, this proofs that someone is actively attacking the application by bypassing the client-side validation.

    And of course, if there is only a ‘client’ application, this application should filter all ‘input’, wherever it comes from.

  • AppSec

    That’s why I always use the phrase:

    Validate at trust level boundaries.. This makes follows the K.I.S.S method.

    In this case, the application shouldn’t trust the data coming to it because it’s not part of it’s binary/scope.

  • Peter Schuler

    A good post. Good wake-up call for me :).

    Agree with AppSec. The point is that data should be validated / escaped at the endpoint, right before you use it..

    In a common web application you need to do this when you ‘render’ the HTML. But as I understand you post there are now new models which require you need to do this client-side. Actually this should also apply to every AJAX based application which downloads additional content from a server. These days with the ‘DNS cache poisoning’ you can never be sure.

  • sherly

    Great writeup !