Being hacked is very painful. Thankfully, I’m not talking about being chopped or slashed with a hacksaw. I’m talking about nasty hacker-types, getting into our websites and doing sometimes silly but often quite nasty things. As developers we always try to minimise the chances of getting hacked by creating secure applications. But even doing our best leaves a gap, because there is always a vulnerability somewhere that can be exploited.
You can never build a perfect system but the more experience you have the less vulnerable your system is going to be. Software security is like the evolution of disease. We create more powerful antibiotics only to be outmatched by more powerful bacteria. It is a never ending war of creating more secure systems only for new vulnerabilities to be found and exploited by hackers.
The scope of software security
Software security covers a very wide area of subjects. To have a secure software application you have to consider many things.
Software security is a layered approach. Everything is interwoven and all the components must be secure. Here is a little diagram I made to illustrate different areas of security, what they cover, and what needs to be considered.
The whole system is only as strong as its weakest link. A hole in any one of the above areas could let in an attacker. It’s fine and good to have the world’s best and most secure data centre but if your root password is “Password123” you may want to look at improving security practices closer to home.
This diagram kind of reminds me of the Stargate.
In this blog I am only going to concentrate on application security. In particular I will talk about what you need to consider as a minimum when writing code.
Application security is a very diverse subject. In this section we are going to talk about some of the more famous attacks and the basics of protecting against them. This needs to be common knowledge for every mid-level developer.
1. SQL Injection
SQL Injection is very famous, dangerous, and easily preventable. The idea is that the attacker can inject SQL code into your database when you are reading user input in your code (for example through post variables, cookies, etc.).
No one can make it simpler and funnier than Randall Munroe of XKCD.
So the solution is to sanitise every time you are building an SQL query using user input.
PHP offers many different ways for sanitising input. Traditionally you would use functions such as mysqli_real_escape_string
Or when using PDO we need to use named parameters and prepare statement:
However in most cases you will be either using a framework or an ORM. Most ORMs and frameworks have internal sanitation functions/methods.
For example if you are using Joomla framework you can use the API provided by Joomla to build your query. Usually the frameworks provide very comprehensive APIs which if used correctly do a very good job of sanitising the input.
There are more information on how to build Joomla queries here:
Next we are going to look at XSS. XSS stands for cross site scripting and is a very common attack in blogs and forums. in XSS the attacker will write a malicious script for example in the comment box of an innocent website and then once this comment is displayed to other users the script will do something malicious to the visitors (e.g. download a virus, send advertising, etc.)
It is very easy to test if you are vulnerable to XSS. Type stuff like the below into your website and save it. If the code runs in the browser then you are definitely vulnerable
The solution is again to sanitise. Use a combination of strip_tags and htmlspecialchars to sanitise both your input and output. Again if you are using a framework such as Joomla you can easily use the built-in sanitisation functions such as the methods available in JInput
CSRF (pronounced sea-surf) stands for Cross-Site Request Forgery. It is also known as XSRF, one-click attack, or session riding and is one of the lesser known attacks.
If you are logged into a website and they don’t protect against CSRF attacks, attackers can hijack your session and do naughty things.
Preventing CSRF requires a random token to be generated and validated against on every request. There are a number of ways this can be implemented. One of the common ways to prevent CSRF while submitting forms is to do the following:
- Generate a token on every request and keep it in the session
- Print the token in a hidden form field
- On form submit check if the token submitted is the same as the one in the session.
- The forger does not have access to the token in your hidden form field so they will not succeed forging the request.
This Stack overflow question explains the pros and cons of different CSRF protection methods:
An even easier solution is to use a framework. Frameworks usually have many features built into them so you don’t need to worry about re-inventing the wheel. For example if you are using Joomla, type in the following line of code in your component controller to prevent CSRF attacks
If you want to sound cool you can do it this way:
Joomla has been built to include many best practice development methods for security. So when using Joomla you don’t need to start from scratch. The above one liner will solve your CSRF problems in Joomla but if you were to implement a token management system from nothing you will need to write many pages of code, and who really has time for that?
During my years of building websites, I have had many painful experiences of being hacked and exploited (and that was just from the Product Owners *bada boom tish*). All these hacking cases were nothing compared to a very mild case of DDoS attack. This was the most serious security problem I ever had to deal with.
DDoS stands for Distributed Denial of Service. The idea is that an army of hijacked computers (called a botnet) will send a lot of request to your website and overwhelm your server.
For maximum effectiveness, each one of the zombie PCs of the botnet will be spoofing their IP. This means the zombie pc is “pretending to be someone else” and once your server tries to respond to them there will be no one there to answer and the server will try again and again.
So one day I realized that our website was down. At first it was really strange because when I restarted the server everything would work fine for a few minutes, then gradually the website would become slower and slower until it became completely unusable. At that point I realised I was dealing with a DDoS attack.
As a developer, there was nothing I could do to help. In every other hacking incident I have experienced before I had made myself useful by cleaning files, restoring the database, changing passwords, or something. But this time there was nothing I could do.
So I called the Australian Internet Security Initiative (AISI). They recommended a couple of DDoS mitigation services. So we quickly subscribed to VeriSign (which was very expensive).
We had to point our DNS to an IP provided by VeriSign. They would then route the traffic through smart algorithms and filter all the malicious requests. VeriSign has an interesting video here describing their process.
There are more advanced services as well in which they will monitor your website traffic permanently and as soon as they identify something dodgy they will trigger the DDoS mitigation service.
DDOS is one of few attacks where there is nothing you can do as a developer to prevent it. Even if you have the most secure system in the world without any vulnerability, you are still prone to DDoS. You can only mitigate DDoS using very expensive services such as the one described above.
The good news is running a DDoS attack is not a cheap or easy thing to do and there is usually a strong motivation behind it. The motivation could range from requesting ransom, to a rogue ex-employee seeking revenge, to competitors wanting to take your website down through unethical and illegal activities.
There are some forensic security specialists that you can commission to find who originated the attack. But they are not cheap, can take a long time, and not always conclusive, especially if the attacker covered themselves well.
I love writing secure code
Software security is a war of skills between the hacker and the programmer. Writing secure code is like playing a tower defence game. You build a castle with amazing defences trying to predict what hackers can do to penetrate and blocking their way even before they try. It is very satisfying to know that you have out-skilled potential future hackers even before they try.
To be able to outmatch hackers, you need to be one step ahead of them. You need to be constantly learning and know about the cutting edge of security.
There are many awesome blogs and interesting resources on software security. Here are some of my favourites:
Dangerous programming mistakesby Jeff Atwood the creator of stack overflow.
Sins of software securityagain by Jeff Atwood
PHP security basics
Joomla secure coding guidelines
Joomla security portal including some more basics for webmasters.
And if you are really really into it:
Extra bonus link:
Writing secure code is more than a skill, it is a state of mind. You need to be constantly informed of the latest security vulnerabilities, threats, and solutions. Read blogs and technical news and constantly apply your knowledge in the code you write.
As you are writing code, you need to constantly think about how your code can be exploited. And come up with counter measures.
Think about it this way, some hackers are paid a full time salary to sit for 8 hours a day and find vulnerabilities in the code we write. Is your code secure enough to withstand that kind of scrutiny?