Hardening Website Security – Part 4: Safely Handling User Input

Introduction

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.

Contents

The series will be consist of the following topics:

1. HTTP Security Headers
    1a. HSTS Preloading
2. User Session Security
3. Database Security
4. Safely Handling User Input

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.

Disclaimer

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.

Section Overview

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.

Potential Attacks

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

Example of normal user input on a comment form
Example of normal user input on a comment form

Here we have a simple web form. When a user enters their name and a comment, it is added to the comments list below.

Example of an XSS attack using a comment form
Example of an XSS attack using a comment form

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.

SQL Injection

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 “&lt;” and “&gt;”. 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.

Conclusion

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: