Why user input should not be trusted and a report into Cross Site Scripting (XSS)
04/06/2014
Why user input should not be trusted and a report into Cross Site Scripting (XSS)
James Hooker, Senior Systems & Developer Support
Share article
Trust, they say, goes two ways. In the grimy world of web development however, this is rarely the case. Your users trust that any information they provide to you is secure, and will not fall into the hands of, or be sold to, any unsavoury character…
Whenever we are given input from the user, we should assume the worst. Any information that comes into the system, should be sanitised, and stripped of any invalid information (or better yet, encoded so that it can cause no harm). If we were to provide the following search string on the form:
“>
Then submit the form, we would have just demonstrated that this script is actually vulnerable to Cross Site Scripting and Content Injection (your mileage may vary – FireFox appears to be the most susceptible to these kinds of attacks, at the moment).
What’s happening here? Basically, we are closing the INPUT tag, and then creating our own IMG tag with n non-existent SRC attribute, and providing an ONERROR attribute with a snippet of JavaScript. When the IMG tag errors out (after receiving a 404 error on the non-existent file), our JavaScript is executed (resulting in an alert stating ‘Hello World!’). Using this same method, we could close the INPUT tag and insert any HTML that we desire, such as an IFRAME, or an external SCRIPT include.
Now thankfully, most modern browsers do protect against this kind of attack (Chrome and IE11 in particular are rather good at this, preventing any JavaScript that was defined in the user input from executing on the page), however there are always workarounds to these protections, such as obfuscating our JavaScript, using invalid HTML (which may cause the protection to not ‘see’ the input as JavaScript), or by injecting HTML elements to load the JavaScript from a remote location.
What can I do to protect my site, and users?
As already mentioned, any input that comes into your application should be sanitised, and possibly encoded. Sanitation should be applied to all fields. Sanitation that could have protected us from XSS in the above example could be something like the following.
User input must only consist of characters a-Z, 0-9 and spaces
If this validation rule were to fail against the ‘URL.searchTerm’ input, then we would clear that Variable, and output an error message. This would force the user to input a valid search term, and prevent the invalid data from being output on our form. Sanitation is also beneficial, as you can always be sure exactly what kind of data is entering your application.
Another option is to encode all user input using the function XmlFormat included in with ColdFusion/Railo. This would encode all values that could interfere with HTML output into something called a HTML Entity. An example of this would be the usage of double-quotes and less than / greater than symbols in the above attack. These would be encoded to ” < and > respectively. Using these functions, even without the above sanitation it would generally be impossible to perform a XSS attack with the provided example.
Jings! What else should I be worried about?
I know this has been said a few times already, but I feel it cannot be re-iterated too many times. All user input should be sanitised. XSS is but one attack vector that a malicious party could exploit. Another very common problem which stems from badly sanitised user input is MySQL Injection. We won’t go into this now, but the basis of MySQL Injection is that a malicious party can inject arbitrary SQL into pre-existing queries, utilizing un-sanitised user input. This can result in catastrophic disclosure of user information, and sometimes even allow the server to be compromised.
There are countless other ways an attacker could compromise a vulnerable web application, but those subjects are for another time.
If you liked reading this article you may also like: