24 ways to make your web application more secure

by Adrian on March 24, 2009

Security has always been an important concern. Today the combination of huge amounts of sensitive information held online and the enormous number of people with online access makes it more important than ever. In many businesses, security is one of the most important requirements to consider when designing web applications. My personal experience of building web applications has been in the financial and healthcare industries, which both place a high priority on effective security.

This post gives an overview of some of the various concepts and techniques that can be used to help secure today’s web applications. It is not meant to be an exhaustive or definitive list. It simply provides a starting point to enable you to conduct your own research and investigation. The vast majority of my personal experience has been gained on the Microsoft Windows platform, but most of the methods can be applied successfully in any environment (e.g. LAMP). To be fully effective, security must be totally integrated into every aspect of your development process. The later in the process security requirements are addressed, the harder and more expensive it becomes to satisfy them. Some of these methods I’ve used myself, whilst others weren’t appropriate to the projects that I’ve been involved in, but may be useful to you.

Analysis Considerations

Model your threats. Decide what information needs to be secured and from whom. This process is known as ‘threat modelling’. It helps identify threats, attacks, vulnerabilities and countermeasures that are relevant to your application.

Understand hackers. Hackers can be motivated in many different ways; some seek a financial reward, others an intellectual challenge. Understanding what motivates hackers is a vital part of threat modelling. There is a good reason why so many hackers are ultimately employed as security consultants.

Use an ‘onion’ layer model. The ‘onion’ layer model is often referred to as ‘defence in depth’. It is a concept based on the realisation that no single security mechanism is infallible. Multiple security methods should be implemented as a series of discrete layers. If one layer is compromised then the intruder is presented with another. The more security layers an application has, the more secure it will tend to be.

Minimise security. This may seem a little odd at first, but security is a cost. In an ideal world where there are no threats security wouldn’t be required. It is important to remember that, like all costs, security should be minimised without risking effectiveness. Too much security can be intrusive and have a negative impact on usability, performance, scalability and maintenance.

Coding Considerations

Don’t mix security and business logic. Security requirements should be implemented separately from business requirements. This can be achieved by using techniques such as inheritance-based frameworks or aspect-orientated programming patterns. Removing the responsibility for security from individual developers simplifies the code that they produce, making them more efficient and their code more maintainable. It also facilitates the use of a standard security model across the whole application, improving its effectiveness.

Catch all exceptions. Ensure that all exceptions are caught and transformed into messages that make sense to the user. If exceptions are allowed to propagate to the user, they can expose information about your business logic and the structure of your database. This information is extremely very valuable to an intruder, as it can provide them with valuable information on which to base an attack.

Ensure that every user is authenticated. Before you allow users access to the application you must ensure that they are who they claim to be. The most common way to do this is to ask them to supply a password when they sign in. Other options include using biometric data, smartcards and digital authentication generators.

Ensure that every user is authorised. Before you allow users access to a specific business function you must ensure that they have the right to use it. User rights are often grouped into user roles, which are then allocated to users. Each user allocated a role has full access to all its rights.

Ensure that all access is audited. Ensure that all access to the application is audited and logged. If a hacker tries to gain access to the application the audit log will record who they were and how and when the attempt occurred.

Never trust user input. Always assume that all user input is malicious, and never process it until it has been validated

Only access data using stored procedures. Only allow data to be accessed using stored procedures. Never allow tables to be accessed directly and never allow the user to submit dynamically created SQL, doing so exposes your database to the possibility of SQL injection attacks.

Force users to use strong passwords. To reduce the effectiveness of dictionary-based attacks ensure users are forced to use a strong password. Strong passwords include one or more numbers, non-alphanumerical characters and are case-sensitive.

Ensure user accounts can be disabled quickly. When an attack is suspected it is vital that the user account that is being used is disabled as soon as possible.

Change passwords regularly. Force users to change passwords on a regular basis. That way if a password is discovered it will only be valid for a short period of time.

Automatically log out users. If a user has been inactive for a prolonged period of time, they should automatically be logged out of the application. This can prevent unattended computers has been used by inappropriate people.

Set a maximum number of failed logon attempts. Set a maximum number of times a user is allowed to submit an incorrect password before their account is disabled. This is to guard against dictionary-based attacks where an intruder will attempt to gain access to a system by repeatedly trying different passwords.

Never store sensitive data without encryption. Never store sensitive data as plaintext, always encrypt it using techniques such as hash functions and salts. That way if an intruder gains access to it they will be unable to decipher what it means.

Deployment Considerations

Choose an experienced managed hosting provider. An experienced managed hosting provider can add credibility to your application’s security, as well as providing a range of useful services and peace of mind. They will ensure your application is situated in a physically secure environment. Most modern data centres employ numerous techniques including biometric scanning and CCTV to ensure that only authorised personnel have access to your servers. They will also log all access to them and use unmarked premises to maintain a low profile.

Use SSL to encrypt sensitive data and ensure trust. The internet is a public communications network. This presents problems for parties seeking to exchange sensitive data. Both need to be confident that the data (e.g. credit card details) will not be intercepted and misused. They also need to be confident that the party receiving the data is who they claim to be. The most common solution to these problems is to use HTTPS over SSL (or TLS as it is now known). HTTPS over SSL uses signed certificates to provide a secure communication channel between two parties. Certificates can either be self-signed by the application vendor, or they can be signed by a trusted third party (known as a certificate authority) such as VeriSign. Certificate authorities (CAs) can provide either standard or extended validation (EV) certificates. EV certificates require more extensive investigation of the requesting party by the certificate authority before being issued.

Use firewalls. Firewalls should be installed to ensure that servers can only be accessed using designated and secured ports (e.g. HTTP port 80, HTTPS port 443, RDP port 3389 etc). An experienced managed hosting provider can supply valuable help with setting up firewalls or any other aspect of network security. This can be particularly valuable if you lack this type of skill in-house.

Deploy across different physical servers. Consider deploying your application across different physical servers. This gives you the option of installing firewalls between each one. If you do this and one layer is compromised, an intruder will only be able to gain access to that particular part of the application. Another benefit of this technique is that you are also able you to lockdown each server to ensure they can only be accessed from other machines within the same trust boundary (i.e. your other servers).

Only allow remote access from authorised IP addresses. Only allow remote access to your live servers from a restricted number of locations (e.g. your office). Never allow your servers to be accessed from any location.

Run your application code under a least-privileged account. Ensure your code runs under a least-privileged user account. This ensures that if an intruder gains access to the application the damage that they can inflict is limited. If you choose to deploy your application this way then it’s important to also develop and test under the same type of account, doing so makes deployment to the live environment much simpler.

Use the operating system security model to access your database. Use Windows Authentication to access your database and ensure that the account you use only has access rights to the appropriate database objects.

Further Reading

Building Secure ASP.NET Applications – Microsoft Press (2003)

Improving Web Application Security: Threats and Countermeasures – Microsoft Press (2003)

Developer Highway Code – Microsoft UK (2007)

Developing with least privilege – Mike Hadlow (2005)

Previous post:

Next post: