In this post we will talk about some quick and easy software security mitigation tricks that every developer can use on a daily basis.
Those quick fixes are called “damage limitation strategies” in general. We would like to talk about 7 practical strategies which you can use while developing your (secure) systems.
Let’s dive straight into them.
As you may already know, input validation is a crucial element of application security and you should know that the easiest way to identify an anomaly is the “length” of your data/input. So, in your system if an input has an expected length, or if we can predict it’s maximum length (more or less), a very good practice would be to set a maximum boundary for your input. As software attacks require big chunks to exploit the system most of the time, strlen functions offer a very cost effective way to safeguard your systems and they are dead easy to use.
OK guys, as a developer you should know the difference between int vs. uint and long vs ulong… etc. You may have heard that “u” stands for unsigned, however if you are not actively using it maybe you are not aware of its potential yet. To refresh your memory, since there will not be a sign for the value you are holding, uint means basically two things:
object Object0. You can store much bigger values object Object1. Values cannot be negative
In terms of software security this might be helpful in a few different ways. Firstly, by default you will be setting a “boundary” for your input which will increase the stability of your system. Besides, this practice will also help you increase your data type awareness.
Boundary limitations are important in software security and strlen and uint/ulong are very helpful for you to create secure systems.
As useful as it is for business logic, type casting or type conversion too, is a very useful risk mitigation tool. During vulnerability assessments we have seen many bad examples of input validation, but the ones who used type-casting were less likely to be affected as the language specific execution routine was protecting the system from unknown inputs.
So, always set your variables to relevant data types. In statically-typed languages this is what you do by default but lazy human brain tends to set variables as a string. Know your types!
In security assessments we like defaults a lot. If anything uses default-something it is way more likely to get hacked. You may be aware of default passwords but that is not exactly what we are talking about.
If you really care about security, try changing every default parameter you use. Consider changing path names (admin, wp_admin, files, logs…etc), database and table names (you can add some prefixes), port numbers, hash functions (use salts), critical snippets and functions etc. Defaults are not good!
Input validation is a painful process and heavily relies on your business logic. Naturally, there is no one-size fits all approach for validating input. However, there are still a few best practices to apply;
First, instead of blacklisting use whitelisting. It is always easier to find a “familiar” pattern than trying to filter harmful inputs.
Second, consider strlen trick and type-casting. Boundary limitations are very good examples of whitelisting. Use them.
Third, encode your data. In some cases, encoding your input may prevent injection attacks (by default).
Fourth, take a look at JSON Schema Validation libraries. It may be extremely useful to sanitize JSON objects.
Fifth, study regular expressions. It is no wonder that many books have been written about them given how powerful and useful they are. Even if you can not dig so deep, at least know the basics. For most inputs even \w filtering may just work perfectly.
[\d] ==> digits
[\w] ==> ASCII printable words
[\s] ==> whitespaces
Secure password storage is complicated! There is only one big recommendation. DON’T STORE PASSWORDS IN PLAINTEXT!
Before starting a project, look for “Most common vulnerabilities” in your programming language. A language specific critical vulnerability might have been released recently which you may not be aware of.
A solid example of these kinds of vulnerabilities could be deserialization vulnerabilities in Java and C#. (Deserialization vulnerabilities may also occur in other languages like python, php, ruby, etc.) Below, you may find links to take a look at “ysoserial” which is a very popular and critical vulnerability that affects Java and C#.NET.
https://github.com/frohoff/ysoserial
https://github.com/pwntester/ysoserial.net
Yet another example could be JavaScript prototype pollution attacks if you are using JavaScript.
Even there are tons of things to say relating to software security, if you are not sure about how to start writing secure code, you can use these 7 recommendations to create a checklist for yourself before you embark on a new project.