Hardening Website Security – Part 4: Safely Handling User Input
It feels like almost every week there’s another news item about personal information being stolen because yet another company’s website got hacked.
Most of these attacks are perpetrated through social engineering, persuading somebody to hand over some detail which allows the hacker to gain additional privileges and, eventually, access to personal information. However, a lot are still carried out due to poor security or misconfigured websites.
This is the second in a series of articles which will aim to demystify some of the concepts you must get your head around if you hope to run a secure website in the 21st century.
The series will be consist of the following topics:
Topics Not Covered
I have opted not to cover server infrastructure security concerns at this time due to the huge number of possible configurations (hosting packages or VPS, operating systems, dashboard systems, firewalls, etc.) While I may cover some of these specifically in future articles, there’s too much nuance in these subjects to be able to do them justice here.
Everything presented in this article is the result of years of experience, or trial and (frequent) error. Messing around with the code and/or settings on a live site can (and likely will) lead to unexpected, possibly disastrous results. The information presented here is correct to the best of the author’s knowledge, but in matters of security we strictly advise the reader to make sure they carry out additional research and understand the dangers before making any changes to their own systems or web sites. Any code presented here is done so as example only, and may be incomplete or contain errors. Readers should be careful when copying and pasting code from any website, this site included. Int64 Software Ltd, its employees and its representatives accept no liability for damage caused by the misuse, either intentional or unintentional, of the information presented in its posts and articles.
In the final part of this series, we’re going to look at the proper way to handle raw user input from your website, and what can go wrong if it isn’t properly sanitized before storing or using the data.
Cross-Site Scripting (XSS)
As covered in previous parts of this series, XSS attacks are used by hackers to inject malicious code into the client side of your website. Successfully deploying an XSS attack can lead to data theft, session hijacking, or malware distribution, so it is critically important that it is prevented.
Example of an XSS attack
Here we have a simple web form. When a user enters their name and a comment, it is added to the comments list below.
An attacker may attempt to enter a script into one of these fields, and if you aren’t properly handling user input you will be vulnerable to attack.
More consisely covered in the Database Security part of this series, an SQL Injection attack may allow an attacker to directly manipulate your database through improperly handled user input.
Rules for Handling User Input in Order to Mitigate Threats
Rule 1: Define an expected data type and enforce it (syntactic)
When designing your forms, think about each input and what type of data you’re expecting to receive. So if you’re asking for a Date of Birth, then make sure that the information received can be parsed to a date correctly; if you’re asking for someone’s age, then make sure it can be parsed to a valid integer.
Failure to fully plan for this rule can lead you to ignoring the validation of a particular field because, for example, it’s a slider which will only ever send numbers, so why worry, right? Wrong: just because you’ve made the form element into a slider, it doesn’t stop an attacker from submitting any data they choose.
Rule 2: Remove unexpected code from the input
Use an established method or library to sanitize potential attack vectors from the input data.
Rule 3: Encode expected code
If you are expecting code in the input, then encode it so that it displays safely without running. For example, you may using an HTML encoding library so that all “<” and “>” characters are rendered into their safe HTML equivalent “<” and “>”. This will mean that, while they still display as the intended character, they won’t cause blocks such as script blocks to open and close.
Rule 4: Define limits and enforce them (semantics)
Ensure that you set appropriate limits for the user input data. This may be specifying a max file size if using a file upload features, maximum string length if receiving text, or a minimum and maximum number if receiving integers.
Rule 5: Beware of directory navigation attempts
If you’re receiving input which may be interpreted as a file or directory on the server, it is critically important that you make sure to limit where that path can go. Watch out for directory navigation imperatives (“../” or “./”) as they may be used to deploy scripts or make changes to critical files on your web server.
Rule 6: When processing arrays, apply all the other rules for each element
Finally, if you receive data from multiple inputs of the same name (checkboxes for example), make sure to apply these rules to every element in the array.
This wraps up our series on Hardening Website Security for now. If you’ve found it useful, we’d appreciate you sharing it with your friends and colleagues, and follow us on Twitter (@Int64Software) for notifications about future articles.
Like the article? Share with your friends: