Web security - OWASP top 10 vulnerabilities
Open Web Application Security Project (OWASP) is a non-profit organisation that was driven by a community which wishes to make the world wide web a safer place. The latest top 10 document can found here. As you can see it is created in 2013, so many of the issues would have been addressed already by new technologies. In this blog, we will be explaining the top 10 vulnerabilities and how they affect the technology today.
Injection
This is something we hear about all the time, mostly known for websites written in PHP that uses MySQL as its database. Since the combination was fairly old technology and it did not have built-in defences against such simple attack. By typing SQL queries into inputs and URL parameters, attackers are able to perform unauthorised actions such as return other user's data or even drop (delete) production databases.
The fix for this issue wasn't difficult. Any website can prevent this by adding type checks on form inputs and URL parameters to ensure injection was not possible. An even easier fix would be to choose or a database management system that has a built-in defence for SQL injection e.g. PostgreSQL. The problem was never with the difficulty of the issue, instead, it was just developers lacked the understanding of this vulnerability or was too lazy to implement checks for 100% of the code base. As a result, a single point of failure could put the entire website risk.
This issue is still an important problem today, this is because there are still many legacy systems out there. If a web was built on today's frameworks, I feel this wouldn't be a problem at all. Modern frameworks are very good at preventing the developer from write code that is prone to this attack.
Authentication/Session management
Many websites require a user to login in order to access more features on a website. To avoid constantly asking the user to type their username and password, a session is used to tell the website the user is already logged in and who he/she is. This vulnerability is when attackers steal user sessions and pretend that they are authorised and have access to information they shouldn't have.
This is a much broader issue since not all website is implemented the same and depending on how it is created the vulnerability could be different. In some cases, the problem could be that a session ID is sent as part of a link that allows anyone to login as the user. There are also ways to steals people's authentication cookie by sniffing over insecure networks. The best way to prevent this is to always ensure session cookie has a timeout period and is regenerated upon every authentication.
This issue has not changed since 2013 since the front end session management and authentication has hardly changed. Sure, there are ways to ensure the websites' security. But the fundamental issue never went away. If the attacker is clever enough and the user is silly enough, there are plenty of ways for the attacker to steal their session e.g. Cross Site Scripting.
Cross Site Scripting (XSS)
Used to be a popular method to embed snippets of code on a legitimate website that could take a user to fake websites and trick them into typing in their credentials so it can be captured by the attacker. There are also many other reasons to perform this type of attack. A simple example of this could be the attacker noticed that a segment of the URL parameter is mapped to a DOM element unconditionally. Thus, by changing the URL parameter to a snippet of JavaScript code could essentially manipulate the DOM element to do as the heart desires.
In modern frameworks, especially front end, there are very little ways to deploy this kind of attack. Frameworks such as Angular, React and etc does not rely on URL parameters as much as jQuery websites do. These frameworks are also much tighter on URL parameters and routeing, it doesn't leave any room for error. On the other hand, modern frameworks also utilise two-way data binding, so gone are the days where values have to be passed as a URL parameter to a DOM element.
Direct Object References
This kind of attack is to do with authorisation, in older websites database record IDs are referred to in the URL parameter (again, yes). If security is not in place, user or an attacker could simply increment the ID value and get someone else's data. Ideally, there should be a check which only allows the user to request their own data. Surprisingly, a few month back a colleague of mine actually found this kind of issue on a live production website for a well-known company. It is pretty much common sense, but yes companies often make this kind of mistakes.
Unlike older websites, newer sites use RESTful APIs to make requests to the server and the URL parameters are hidden from the browser address bar. But the problem is still there, an attacker could still fake a request (a tiny bit more work than altering the URL) to the server asking for someone else's data. So correct security checks must be in place, this is extremely important for public facing APIs since everyone on the internet could access them.
Security Misconfiguration
There are new system and software vulnerabilities are found all the time, thus it is very important to keep everything up-to-date. Companies, especially larger companies, are always reluctant to upgrade because new changes could break their software and cause incompatible issues. I mean look how many times companies paid Microsoft to not drop support for Windows XP when windows 8 was already out. Imagine the vulnerabilities on a system that is almost 13 years old. Other ways to reduce risks of vulnerabilities are to disable ports, services and accounts if they are not being utilised. Speak of accounts, ensure all default passwords are changed to something more secure, e.g. router or database passwords.
There are probably a million other things to do and your system might still be vulnerable. But here are 3 areas to start securing:
- Turn off features that are not needed and apply the "principle of least privilege"
- Change default settings, and ensure production-ready (turn off debugging, and limit admin access)
- Always try to stay up-to-date in terms of tools, software and systems
Sensitive Data Exposure
This issue covers the lack of SSL (HTTPS) implementation of websites, using secure connection prevents a lot of issues such as "Man in the middle" attack. The password is obviously one of the most important user data, so the lack of encryptions could lead to database table being decrypted and leaked after one point of failure e.g. Inject. If the encryption is strong enough, even if the data is stolen the attacker can't do anything with it (a strong encryption could take hundreds of years to decrypt). It is almost silly not to use strong algorithms to ensure the security.
Companies often try to capture as much of user information as possible, what businesses don't understand is that unless the data adds value recording it simples puts the company more at risk. By capturing fewer data, it might mean a much better end result if the system was compromised and user data was stolen. As a user, I definitely prefer to only have my email address leaked, compared to all of my personal information e.g. date of birth, address and etc. Having more user data might attract more attackers in the first place, since they know they can get all the data they need just by hacking your company. So to both reduce potential damage and cost, only record data that is absolutely necessary.
HTTPS is currently being pushed by a lot of companies, Google being one of them. Soon Chrome will start marking websites as insecure if they do not have HTTPS connection. Let's Encrpty also provides free SSL certificates for any website for free, again to push for a more secure online experience.
Function Level Access Control
This issue is similar to the "Direct Object References" section, but just on a more general. It is important to prevent the UI from showing unauthorised functionalities. If a user should not have access to a button don't just disable it, hide it completely. It is also worth noting just because a page is not navigatable doesn't mean the attacker can't find it by looking through the code, so prevent user going to that page altogether in the routeing.
As mentioned already, it is crucial to perform all the security checks on each and every public facing APIs. This includes checking if the user is authenticated, authorised, has the correct privileges, and etc. It is important to have validation on the front end, but API level testing is more important. Since it is extremely easy to bypass front end validations and checks.
Cross-Site Request Forgery (CSRF)
This attack is very clever, almost like a puppet master controlling the user to do their biddings. Often, the attacker will trick the user from making requests to important requests (e.g. doing a bank transfer to the attacker). This could be a fake website, this could also be part of an XSS attack.
To prevent this type of attacks, there are a few things we can do:
- Anti-forgery tokens, that is generated randomly instead of sending the same token every time
- Valid requests only from known origins and referrers, fraud detection patterns
- Some browsers already have built-in defences for this e.g. Chrome prevents cross-origin requests
Using Components with Known Vulnerabilities
Component and version could be discovered by studying the request headers, file name patterns and etc. We already know that the components have vulnerabilities, so it is a lost battle right? Kind of, it is pretty difficult to defend against this kind of issues. The best thing to do is to update to a newer version with a fix as soon as possible or to move away from unsafe components.
Unvalidated Redirects and Forwards
You probably already noticed as we move down the list, the amount of description and text is decreasing. This is because attacks such as this one have a much less impact than issues such as SQL injection. The concept of this attack is when attacker changes redirect links on a website, so they are redirected to other malicious websites. At this point we are assuming, the original website has already been compromised and this attack is simply a way to spread malware to more users. This is so low in terms of importance, companies like Google doesn't even offer bug bounties for reporting this kind of issue on their sites.
Conclusion
Security is a constant battle, it is also an on-going issue in terms of support and maintenance. As explained already some of the issues are already ageing, and might disappear in a few years when all the frameworks contain built-in support for these type of attacks. At the same time, more issues will appear, for frameworks like Angular its implementation is very predictable thus may allow attackers to think of new ways of attack. To conclude, I feel some of the issues are definitely worth bearing in mind when developing new products. A lot of the issues mentioned above are to do with the backend system and backend development has not changed that much in the past few years. Although new database technology such as MongoDB does not have any vulnerability towards query injection and more websites will be adopting HTTPS, so I guess somethings are changing and for the better too.