Input validation is not only about security. It is also about building user-friendly applications (a message when the data-entry does not comply) and keeping data consistency (all data is stored in the same format). In example, you can choose to store all dates in yyyy-mm-dd format in your database. When you make sure you do that, you can easily analyze and generate statistics of the data in your database. When a user of the system enters data in a wrong format, you can either automatically change it (sanitization), or send a message to the user to enter it in the correct format.
Part 1 - Input validation process
Part 2 - Input validation coding client-side
Part 3 - Input validation coding server-side
But first, lets take a look at OWASP.
OWASPOWASP stands for Open Web Application Security Project. Their mission is to improve security of software. Short and fairly simple statement, but a very important one. They also track down the most often used (or rather misused) vulnerabilities that are present in (sometimes poorly) written software.
This is the list with the top 10 vulnerabilities in 2013.
- Broken Authentication and Session Management
- Cross-Site Scripting (XSS)
- Insecure Direct Object References
- Security Misconfiguration
- Sensitive Data Exposure
- Missing Function Level Access Control
- Cross-Site Request Forgery (CSRF)
- Using Components with Known Vulnerabilities
- Unvalidated Redirects and Forwards
From that list the following vulnerabilities can be mitigated with proper input validation.
- Cross-Site Scripting (XSS)
The input validation process
- Check if the input is actually sent and received
This check is to prevent any "null" or "not defined" errors when you execute step 2 in this process. If there is no (required) value being sent, the process can and should stop here.
- Store input in memory, separate it from the source
Store the input in memory, for example a variable (no permanent storage!). This is to separate the input you are going to check from the actual source of the input. When you don't do this, the attacker might alter the data later in the process.
- Check variable for, and remove all scripting
In this part we check the variable for scripting. Scripts in input variables might cause havoc on systems but injecting malicious code.
- Trim the variable
Trimming is a process to remove all preceding and trailing spaces, tabs, and more of a variable. This keeps data in the database clean and helps with preventing a buffer overflow. Buffer overflow happens when you want to store a variable in a record, but the record is smaller than the variable and thus resulting in a buffer overflow which can be misused by an attacker.
- Truncate the variable to the maximum size of expected value
This is the second step in preventing a buffer overflow. When all the spaces are gone, you will discard all data in the variable that exceeds the maximum storage of that record and its attributes. This step might be optional when you are processing data in text form, but think about this step thoroughly and carefully.
- Check if it is the correct variable type and/or format
This step will check if you got the the type of variable you are expecting and if it is in the right format. Do you only expect a numeric value? Or do you expect a string? But also consider date-formats, URLs, and email addresses. This is the place to check for it. When incorrect you can either drop the input or convert it (sanitization) to the proper type.
- Check if it is expected content (also called white listing)This is an important and probably most difficult step to work out in the code when handling specific data. For example, in some cases you might expect an URL which always preceeds with "https://www.google.com/". So when you have received and processed your input, the last step is to check if you see that the variable meets your requirements. This is a content-specific check to prevent unauthorized data being send to your application. This can be different for every type of input in your application.
- When relevant, check existence of local resources
This step is probably only relevant when you are processing input that is pointing to local resources. Think about files an user can upload, or an URL you convert to a local resource. In these cases, always check if the resource (file, database, etc) exists, before actually accessing it. The reason that this step is at the end, is to prevent malicious code being executed when you access the local resources on your web- or application servers.
- And now is it input for the process
All checks are done, it is safe (as it can be) to process the input. This can be storing it in the database or presenting it the Graphical User Interface of your application. Don't forget to close the connection or resources you accessed in your entire process when you don't need it anymore.
When and where?
This improves the user experience in your application, and it contributes to the layered-defense principle. If the client-side defense layer fails (because the attacker is circumventing the form or regular ways of submitting input), you will have your second layer of defense ready, and that is the server-side input validation.
- Open Web Application Security Project (OWASP) - https://www.owasp.org/
- Open Sourced Vulnerability Database (OSVDB) - https://osvdb.org/
- TestingSecurity.com - http://www.testingsecurity.com/
- The importance of input validation, by Kevin Beaver - http://searchsoftwarequality.techtarget.com/tip/The-importance-of-input-validation
To be continued...
Thank you for reading my blog!