For all too many online companies, it’s not until after vulnerabilities have been located and a data breach has occurred that website security becomes a priority. With daily instances of small and large-scale hacks, it’s odd that many still maintain the “it won’t happen to me” attitude until it happens to them.
An effective approach to website security must be proactive and defensive. The idea here is to inject the reader with a healthy dose of paranoia so that website security measures can be taken now.
Common Mistake #1: Injection flaws
Injection flaws result from a classic failure to filter untrusted input. It can happen when you pass unfiltered data to the SQL server, to the browser, to the LDAP server, or anywhere else. The problem here is that the attacker can inject commands to these entities, resulting in loss of data and the hijacking of clients’ browsers. Anything that your application receives from untrusted sources must be filtered.
Prevention: The good news is that protecting against injection is a matter of filtering your input properly and thinking about whether an input can be trusted – without question.
In a system with 1,000 inputs, for example, successfully filtering 999 of them is not sufficient, as this still leaves one field that can bring down your system. And you might think that putting an SQL query result into another query is a good idea, as the database is trusted. But if the perimeter is not safe, the input could come indirectly from people with malintent.
Common Mistake #2: Broken Authentication
This is a collection of multiple problems that might occur during broken authentication, but they don’t all stem from the same root cause. Assuming that anyone still wants to roll their own authentication code, I advise against it. It is extremely hard to get right, and there are a myriad of possible pitfalls. Here are a few:
~ The URL might contain the session id and leak it in the referer header to someone else.
~ The passwords might not be encrypted either in storage or transit.
~ The session ids might be predictable, thus gaining access is trivial.
~ Session fixation might be possible.
~ Session hijacking might be possible, timeouts not implemented right or not using SSL.
Prevention: Is was the case for Mistake #1. the most straightforward way to avoid this web security vulnerability is to use a framework. You might be able to implement this correctly, but the former is much easier. In case you do want to roll your own code, be extremely paranoid and educate yourself on the several pitfalls of doing so.
Common Mistake #3: Cross Site Scripting (XSS)
Prevention: There’s a simple web security solution: don’t return HTML tags to the client. This has the added benefit of defending against HTML injection, a similar attack whereby the attacker injects plain HTML content (such as images or loud invisible flash players). These are not high-impact issues, but they can be annoying. One method of sanitization is using regular expressions to strip away HTML tags using regular expressions, but this is dangerous as a lot of browsers will interpret severely broken HTML just fine. Better to convert all characters to their escaped counterparts.
Common Mistake #4: Insecure Direct Object References
This is a classic case of trusting user input and paying the price in the form of security vulnerabilities. A direct object reference means that an internal object such as a file or database key is exposed to the user. The problem with this is that the attacker can provide this reference and, if authorization is either not enforced (or is broken), the attacker can access or do things that they should be precluded from.
For example, the code has a download.php module that reads and lets the user download files, using a CGI parameter to specify the file name. Either by mistake or due to laziness, the developer omitted authorization from the code. The attacker can now use this to download any system files that the user running PHP has access to, like the application code itself or other data left lying around on the server, like backups.
Another common vulnerability example is a password reset function that relies on user input to determine whose password we’re resetting. After clicking the valid URL, an attacker can just modify the username field in the URL to say something like “admin”.
Prevention: Perform user authorization properly and consistently, and whitelist the choices. More often than not, the whole problem can be avoided by storing data internally and not relying on it being passed from the client via CGI parameters. Session variables in most frameworks are well suited for this purpose.
Common Mistake #5: Security misconfiguration
In my experience, web servers and applications that have been misconfigured are way more common than those that have been configured properly. Perhaps this because there is no shortage of ways to screw up. Here are some examples:
- Running the application with debug enabled in production.
- Having directory listing enabled on the server, which leaks valuable information.
- Running outdated software (think WordPress plugins, old PhpMyAdmin).
- Having unnecessary services running on the machine.
- Not changing default keys and passwords.
- Revealing error handling information to the attackers, such as stack traces.
Prevention: Have a good (preferably automated) “build and deploy” process, which can run tests on deploy. The poor man’s security misconfiguration solution is post-commit hooks, to prevent the code from going out with default passwords and/or development stuff built in.
In Part 2 of this post, we’ll uncover five more vulnerabilities. Be sure to read it here, as having half the story is like protecting half of your website.
To receive malware and vulnerability scanning of your site on a daily basis from an approved scanning vendor, contact Trust Guard or click here.
Special thanks to Gergely Kalman, a security specialist at toptal.com/security for his article on the same topic and from which much of the information for this article was utilized.