10 Best Practices to Build Secure Applications
Recently, here on the blog, I’ve been talking about security quite a bit. It’s both a fascinating topic as well as an important one. Especially given the number of high-profile security breaches over the last 12 – 24 months.
Today, I want to consider ten best practices which will help you and your team secure the web applications which you develop and maintain. I’d like to think that these won’t be the usual top 10, but rather something a little different.
My intent is to help you look at the security of your application in a holistic manner and give you a range of ways to ensure that it’s as secure as it can be, as well as forever improving. Let’s start with number one.
1. Follow the OWASP Top Ten
I’ve already covered this in greater depth, in a recent post. But, it’s still a crucial list to keep in mind. If you’re not familiar with the OWASP Top Ten, it contains the most critical web application security vulnerabilities, as identified, and agreed upon, by security experts from around the world.
These security vulnerabilities target the confidentiality, integrity, and availability of an application, its developers, and its users. They cover such attack vectors as injection attacks, authentication and session management, security misconfiguration, and sensitive data exposure.
By being aware of them, how they work, and coding in a secure way the applications that we build stand a far better chance of not being breached. Doing so also helps you avoid being on any end of year hack list.
The list, surprisingly, doesn’t change all that often. Sadly, many of the same issues seem to remain year after year, despite an ever growing security awareness within the developer community.
This is both a blessing and a curse. As they don’t change often, you can continue to review the preparedness of your application in dealing with them.
2. Get an Application Security Audit
Let’s assume that you take the OWASP Top Ten seriously and your developers have a security mindset. Let’s also assume that they self-test regularly to ensure that your applications are not vulnerable to any of the listed breaches. You may even have a security evangelist on staff.
While these are all excellent, foundational, steps often they’re not enough. This is because of preconceived biases and filters. Your team lives and breathes the code which they maintain each and every day. Because of that, over time, they’ll not be able to critique it objectively. Increasingly, your team will be subjective in their analysis of it.
It’s for this reason that it’s important to get an independent set of eyes on the applications. By doing so, they can be reviewed by people who’ve never seen them before, by people who won’t make any assumptions about why the code does what it does, or be biased by anything or anyone within your organization either.
Additionally, they will be people with specific, professional application security experience, who know what to look for, including the obvious and the subtle, as well as the hidden things. They’ll also be abreast of current security issues and be knowledgeable about issues which aren’t common knowledge yet.
Specifically, what I’m suggesting is to get an application security audit carried out on your application. They can give you a baseline from which to grow.
This can be potentially daunting if you’re a young organization, one recently embarking on a security-first approach. But, setting concerns aside, security audits can help you build secure applications quicker than you otherwise might.
3. Implement Proper Logging
Now that you’ve gotten a security audit done you have a security baseline for your application and have refactored your code, based on the findings of the security audit, let’s step back from the application.
Let’s now look at the bigger picture, and look at the outside factors which influence the security of an application. Specifically, let’s look at logging.
Invariably something will go wrong at some stage. There’ll be a bug that no one saw (or considered severe enough to warrant particular attention) one that will eventually be exploited.
When that happens, to be able to respond as quickly as possible — before the situation gets out of hand — you need to have proper logging implemented.
Doing so provides you with information about what occurred, what lead to the situation in the first place, and what else was going on at the time. As the saying goes: proper preparation prevents poor performance.
To do so, first, ensure that you’ve sufficiently instrumented your application. Depending on your software language(s), there is a range of tools and services available, including Tideways, Blackfire, and NewRelic.
Secondly, store the information so that it can be parsed rapidly and efficiently when the time comes. There is a range of ways to do this. From simple solutions such as the Linux syslog, to open source solutions such as the ELK stack (Elasticsearch, Logstash, and Kibana), to SaaS services such as Loggly, Splunk, and PaperTrail.
Regardless of what you use, make sure that the information is being stored and that it’s able to be parsed quickly and efficiently when the time comes to use it.
4. Use Real-time Security Monitoring and Protection or Web Application Firewalls
Any consideration of application security would be incomplete without taking classic firewalls and web application firewalls into consideration.
As I wrote about recently, firewalls, while effective at specific types of application protection, aren’t the be all and end all of application security.
This is the case for a number of reasons, including that they can generate false positives and negatives, and can be costly to maintain. However, they do afford protection to your application.
So, I suggest that you use them in addition to Runtime Application Self-Protection (RASP) and services such as Sqreen, to provide real-time security monitoring and protection.
That way, you can protect your application from a range of perspectives, both internal and external.
5. Encrypt Everything
Now that your application’s been instrumented and has a firewall solution to help protect it let’s talk about encryption. And when I say encryption, I don’t just mean using HTTPS and HSTS. I’m talking about encrypting all the things.
I believe it’s important to always use encryption holistically to protect an application. This might seem a little Orwellian, but it’s important to consider encryption from every angle, not just the obvious or the status quo.
It’s great that services such as Let’s Encrypt are making HTTPS much more accessible than it ever was before. And it’s excellent that such influential companies as Google are rewarding websites for using HTTPS, but this type of encryption isn’t enough.
It’s important to also make sure that data at rest is encrypted as well. HTTPS makes it next to impossible for Man In The Middle (MITM) attacks to occur.
But if someone can get to your server (such as a belligerent ex-staffer, dubious systems administrator, or a government operative) and either clone or remove the drives, then all the other security is moot.
So, please don’t look at security in isolation, or one part of it. Look at it holistically and consider data at rest, as well as data in transit.
6. Harden Everything
Now that all traffic and data is encrypted, what about hardening everything? From operating systems to software development frameworks you need to ensure that they’re sufficiently hardened.
This is too complex a topic to cover in the amount of space I have available in this article. So let’s instead consider a concise list of suggestions for both operating systems and frameworks.
- Is your web server using modules or extensions that your application doesn’t need?
- Is your software language using modules or extensions that it doesn’t need?
- Does your software language allow remote code execution, such as exec and proc to occur?
- What’s the maximum script execution time set to?
- What access does your software language have to the filesystem?
- Where is session information being stored?
- Are the servers, services (such as MySQL, PostgreSQL, and Redis) and software language configuration files write protected?
- Are your servers using security extensions such as SELinux or AppArmor?
- Is incoming and outgoing traffic restricted?
- What users are allowed to access the server and how is that access managed?
How do your servers, services, and software language configurations fare? This is a complex topic. So, here is a short list of best-practice guides to refer to:
7. Keep Your Servers Up to Date
In addition to ensuring that your operating system is hardened, is it up to date? It could very well be hardened against the current version, but if the packages are out of date (and as a result contain vulnerabilities), then there’s still a problem.
Make sure that your servers are set to update to the latest security releases as they become available. I’m not suggesting updating each and every package, but at least the security-specific ones.
Depending on your organization’s perspective, you can elect to automate this process. Alternatively, you can review and approve updates individually.
If you want to automatically install security upgrades, you can use:
If you’re not using one of these, please refer to the documentation for your operating system or distribution.
8. Keep Your Software Up to Date
As well as keeping the operating system up to date, you need to keep your application framework and third party libraries up to date as well.
Some people may scoff at the thought of using a framework. That’s not a debate that I’m going to engage in today, suffice to say that they both have their place, and when used well, can save inordinate amounts of time and effort.
Frameworks and third party software libraries, just like operating systems, have vulnerabilities. If they’re properly supported, then they will also be rapidly patched and improved. Given that, it’s important to ensure that you’re using the latest stable version — if at all possible.
Most languages, whether dynamic ones such as PHP, Python, and Ruby, or static ones such as Go, have package managers. These tools make the process of managing and maintaining external dependencies relatively painless, as well as being automated during deployment.
Ensure that you take advantage of them and stay with as recent a release as is possible.
9. Stay Abreast of the Latest Vulnerabilities
This is strongly tied to the previous point. Given the number of attack vectors in play today, vectors such as Cross-site scripting, code injection, SQL injection, insecure direct object references, and cross-site request forgery it’s hard to both stay abreast of them as well as to know what the new ones are.
But, such is life. Given the world in which we live and the times in which we operate, if we want to build secure applications we need to know this information. Gladly, there are a range of ways in which we can get this information in a distilled, readily consumable fashion.
Here is a list of blogs and podcasts you can regularly refer to, to stay up to date:
10. Never Stop Learning
Finally, perhaps this is a cliché, but never stop learning. You may be all over the current threats facing our industry. But that doesn’t mean that new threats aren’t either coming or being discovered.
Given that, make sure that you use the links in this article to keep you and your team up to date on what’s out there. Then, continue to engender a culture of security-first application development within your organization.
That way, you’ll always have it as a key consideration, and be far less likely to fall victim to security or data breaches.
That’s been 10 best practices for securing your web application. No one article is ever going to be able to cover ever topic, nor any one in sufficient depth. The security landscape is changing far too quickly for that to be practical.
However, with the information here, you’re equipped with 10 best practices to guide you on your journey to building secure applications. Make sure that you use them and consider security as equally as important as testing and performance.
About the Author
Matthew Setter is an independent software developer and technical writer. He specializes in creating test-driven applications and writing about modern software practices, including continuous development, testing, and security.