12 Rules for Security – An Antidote to Chaos

Basic guidelines to keep your programming secure

Everyone remembers their teen years– all the changes and insecurities. We can all be vulnerable and crave security.  The same is true for computers. 

Today, we rely on so much technology that all use a computer-based solution. So keeping the solutions secure is more important than ever, and security vulnerabilities can affect anyone, from individuals to large corporations. In 2010, for example, a virus of “unknown origin” affected the Iranian nuclear program. The Stuxnet virus, as it became known, almost shut the entire program down. 

A security breach can damage companies’ reputations and cause significant financial losses. So, how do we mitigate and prevent security threats?

Secure Programming

Secure programming has a few basic steps which should be respected. It is important to note, however, that this is not a magic recipe that can be used to fix insecure projects– if a project wasn’t built securely, making it secure requires lots of hard work and testing.

A good place to start is the OWASP Top 10, which lists the “most critical security risks to web applications.” Overall, you should prepare your code with the mindset that someone will try to attack it. If a software interacts with different users or lives on a machine with internet connection, someone will likely try to hack it. 

There are many guidelines to follow to keep your program secure. With three years of experience working as a security adviser in a web development context, I’ve discovered an antidote to chaos by following these 12 principles: 

I. Respect the classics

Remember when you learned programming? Remember all those basic rules the teachers or the books taught us? Good. Because respecting the basics will save you lots of trouble. Just name your variables as they should be named, respect encapsulation, respect basic design patterns, and so on. 

II. Change the defaults

Usually every system comes with access management and credentials. If it doesn’t, then there’s either a good reason for it or it is a bad system. Review all the servers, databases and other systems and update the username and password. Start with the machine which the servers will inhabit. Also, never run your code with root access rights. Change the database server’s password, the apache default password, Drupal credentials and whatever else you are using.

III. Limit resource usage

Limit the hardware usage of your application. Close all opened ports which are not used, disable or uninstall unused features. Hackers can learn about certain vulnerabilities of the system components and use them to infiltrate your network or machine. So always enable only ports you are using. 

IV. Proper user management

It’s tempting in development to run the code using elevated rights. Everything works fine, the user has access to the system’s resources, and so on. However, it is a good practice in production to allow the code or project to run with a user who has access only where it needs it. A good example for this is a path traversal attack. Usually a resource, like a pdf file, can be stored in a static folder. However, an attacker can try setting a relative path to sensitive files and try downloading those. If the site or project doesn’t have the rights to access sensitive files and folders, path traversals can be stopped.

V. Proper virtualization

The days when websites were deployed on proprietary servers are long gone. Nowadays, everyone is talking about the cloud. Everybody talks about it, but no one actually understands it. So when you deploy your product or website in the cloud, just make sure that you have snapshots which can be used in case the system fails.

VI. Test, test, test

This is a sensitive topic– testing doesn’t bring any revenue, but it stops errors, data leakage, and so on. Also, it helps improve company reputation by helping to provide a proper bug-free user experience. When it comes to security, it’s a never-ending race between attack and defense. Perform a periodic security audit on your code, and don’t forget about automated testing.

VII. Third party apps proper management

In software development you don’t have to reinvent the wheel. There are many frameworks and libraries out there which can help and drastically reduce the development time necessary for a project. However, the frameworks and libraries also age and have known vulnerabilities. The best example for this is the Log4j issue, where every website or project which used it suddenly became vulnerable– or at least those who didn’t respect the basic security elements.

Apps like Drupal or Apache are very helpful. However, specific versions of them have certain known bugs. This is the reason why it is recommended to always have (if possible) the latest version of a third party app or library. It is not ok to run, for example, a jQuery version which came out in 2010 just because it works. 

VIII. Prohibit information leakage

This rule is relevant to all projects, but the examples presented are from a web development process.

As mentioned in the previous rule, different versions of the third party apps can have different known bugs or vulnerabilities. If an attacker knows what version of a certain third party tool we are using it can try the known vulnerabilities first. 

The same thing is relevant for programming languages. Some versions have known issues, which are patched in the following releases. However, if for some reason our codebase didn’t make the upgrade it can be vulnerable. We are giving an attacker a helping hand if we return in a http header sensitive information about our Drupal version, PHP version, Nginx or Apache powered by, for example. This information might be helpful or needed in development, but they are certainly not required in production.

Information leakage can also happen when error messages are too specific. A good example would be a sign in mechanism, which, in case of a failed login, notifies the user that the password was wrong. In this case an attacker can guess the valid email and then can focus only on breaking the password. The proper solution would be to show only a generic error message without specifying the details.

IX. Bury the dead

During a product or a website lifecycle certain features age and then they are no longer maintained or even used. They just live like zombies in the codebase’s nomansland and are there for an attacker to exploit them. For this reason, it is recommended to remove or archive unused code.

X. OWASP – XSS protection

The last three rules are from OWASP and they are mostly encountered in web development context. The first of these is XSS protection. What is XSS? It’s a shortcut for cross-site scripting. In short, XSS is the execution of injected code on the client side. For example, in the comment section of an article or a blog post which is vulnerable to XSS, someone adds a comment which contains executable JavaScript code. When a new reader accesses the page and checks the previous comments, the attacker’s js code is automatically executed. Protecting against XSS is relatively simple: make sure that absolutely everything that comes from the user is sanitized.

XI. OWASP – Use secure context

This rule might be trivial for people working in a software development context, but it is still important and must be mentioned. If you are building a website, don’t be cheap– buy a https encryption key. Unsecure websites are an open invitation for an attacker to hack. The rule of thumb here for the average user is that if a website doesn’t have https or the browser notifies that some certificate error occurred, discontinue navigating that site and, certainly, do not buy anything on that website.

XII. OWASP – CSRF protection

What is CSRF? Basically, when navigating on a website the used http protocol is stateless. In order to simulate a state, we use cookies. Cookies can build a session. A session cookie is a cookie which is sent with every single request made from the same browser. However, an attacker can capture your session cookie or might steal it. To mitigate this we can add a so-called unique token to each request, i.e. a CSRF token. In order to have a successful navigation a request must provide to the server the session cookie and the secret token value, as well.

Conclusions

Security in software development is a complex matter. There is no magic solution. It is a long procedure which has to be embedded in the life cycle of the project. The best case scenario would be that everyone involved in the development process, from business analyst to developer and tester, from delivery manager to stakeholder, understands the importance of having a secure application and stops treating security as a nice-to-have feature.

There are no shortcuts in life nor in software development. Respecting the twelve principles might not create an impenetrable fortress, but it certainly will make an attacker sweat.