The Open Web Application Security Project (OWASP) has been releasing its Top 10 list of common risks since 2003. The OWASP Top 10 2017 is the latest release in a long line of Top 10 lists. There are some risks that stick around from iteration to iteration. Some are new, some have left.
If you’re a developer, you can help eliminate these risks from the next Top 10 list.
If you’re a CISO, security engineer, or software development manager, use the list to find where your applications need help. Create a strategy that will change the list in the future.
Developers have power over this list. The list is based on data about real applications that are in production right now. When developers learn how to effectively prevent these risks in their own applications, the list will change.
An example: Cross-Site Request Forgery (CSRF) is no longer on the list because it was found in only 5% of applications.
Let’s talk about what each entry is, how it works, and how you or your developers can help eliminate it from the next list.
OWASP Top 10 2017 – 1: Injection
Injection is an old, yet still prevalent, vulnerability. The community has known about it for some time. However, it has changed over the years in ways that likely couldn’t have been predicted.
How it works
Injection comes down to data being interpreted as code. Computers, tricked into thinking that input coming from the user is really code, happily execute it. Malicious actors love this behavior and use it to run arbitrary code within your application.
Injection has been number one from the start because of its massive impact, prevalence, and ease of exploitation. Once someone can run code just by entering clever text into input boxes on a screen, they can do almost anything.
OS command injection allows them to run command on the application server, such as opening an ssh connection or command prompt.
SQL injection tricks your database into spitting out sensitive records that the attacker shouldn’t have access to or sometimes making modifications to the database itself. Unfortunately, there are free tools out there that an attacker can use to pull this off with a push of a button.
The new kid on the block is NoSQL injection. Some frameworks provide good protections against SQL injection, but NoSQL injection is still widely unknown and just as dangerous.
NoSQL injection targets NoSQL databases such as MongoDB. An attacker can craft some clever text that brings back every record in the database. Just because it’s not a relational database, doesn’t mean it can’t be attacked.
How you can help
How can developers help knock this risk out of the number one spot on the OWASP Top 10? First, understand how your frameworks protect you.
Python Django has a built-in ORM.
Java has Hibernate.
.NET has Entity Framework. Use it. That is all.
Bottom line, whatever you use as your language of choice, there’s likely an Object Relational Mapper (ORM) framework you can use that will wipe out SQL injection from the start.
If you prefer creating your own SQL queries, parameterize them. Don’t allow user input to go straight into a query without checking it first.
NoSQL injection is a bit tougher. For example, MongoDB allows you to define a JavaScript function and pass it into its find() function. It looks like this
1
2
3
4
5
|
db.myCollection.find({ $where: function () { return obj.credits - obj.debits < 0; } }); |
Issues crop up when that function can be manipulated by an attacker. Don’t put untrusted data that hasn’t been validated into this function ever. Some frameworks, such as Mongoose for Node.js, mitigate this risk. If you are using other languages with MongoDB, keep a look out for NoSQL injection.
Injection is number one. Let’s take it down:
- Validate input
- Parameterize queries
- Use an ORM
- Don’t use input for MongoDB queries without validation
- Did I mention validate input?
OWASP Top 10 2017 – 2: Broken Authentication
Broken authentication would be number one if NoSQL injection didn’t exist. So this one can easily bite developers if they aren’t careful.
How it works
Authentication can be tough to pull off. Applications that can be attacked using authentication exploits are usually guilty of one of these four things:
- Poor session management
- Having no protection against automated attacks
- Allowing default, weak, or well-known passwords
- Poor execution of “forgot password” functionality
Broken authentication means that an attacker can impersonate a legitimate user. Robust authentication can be difficult, but it is possible.
How you can help
Developers can kill this entry in the Top 10 by double-checking their strategy for authenticating users.
Many frameworks have some sort of identity management. For example, Node.js Passport and ASP.NET Identity can help you build robust authentication mechanisms.
Frameworks can help you by giving you access to industry best practices out-of-the-box. On the other hand, you are giving up some freedom and flexibility in how you want to handle authentication. Each development team will need to decide for themselves which is preferable.
You generally don’t want to roll your own auth scheme. If for some reason you must, here are some ways to not screw it up:
- Build multi-factor authentication into your system
- Protect passwords by storing them using strong hashes
- Implement protections against automation
- Avoid default and hard-coded passwords
- Check new or changed passwords against the 10,000 worst passwords and don’t allow those that are on the list
- Use good session management techniques (lean on your frameworks for help)
OWASP Top 10 2017 – 3: Sensitive Data Exposure
Sensitive data is what all the bad guys want (if they aren’t mining cryptocurrency). It’s your greatest asset and the most dangerous if it gets out. No only will your customers be put at risk, you my end up paying out massive fines to regulators.
Sensitive data must be protected above all else. All of these other risks and vulnerabilities usually are just the stepping stone to data. That’s what is valuable and can be sold for tons of money.
How it works
Unfortunately, when it’s stored in the open and has no protections on it, data is pretty easy to grab. You must be careful with your data. Even honest mistakes can have a large impact.
Some leave huge amounts of data on publicly exposed S3 buckets. Others store data unencrypted in a database that gets whacked with SQL injection.
Either way, it’s ugly. The average cost of a data breach in 2019 was $3.92 million. That is a hard hit to take no matter who you are.
How you can help
Data breaches can happen when other vulnerabilities are exploited. This leads to a high focus on protecting databases against SQL injection and encrypting network traffic.
That’s a good start, but there are more subtle ways for data exposure to creep up. Unencrypted backups stored in S3 buckets are likely targets. Storing a file on a server called “January Terminations.docx” probably isn’t a good idea either.
Even more subtle is the sensitive data held within error messages. If debug or detailed stacktraces are returned to the client, you could be revealing the inner workings of your code or even your database. This will make attacks easier for the attacker.
Bottom line: think about who can see the data. Know what data should be seen and what needs to remain private, even within the organization.
Here’s what you need to do to knock this one off the list:
- Know what data is sensitive and what isn’t
- Encrypt data that is sensitive
- Store passwords properly
- Encrypt backups and be careful where you store them
- Use HTTPS
- Discard data you don’t need
- Don’t cache sensitive data
Follow these steps and sensitive data exposure will go down.
OWASP Top 10 2017 – 4: XML External Entities (XXE)
Now we get to the first newcomer to the list. XXE has never been on the list before and has entered the arena with a bang.
It’s so high because this risk can cause quite a bit of damage and is often not tested for by penetration testers. It allows for arbitrary code execution on the server. That’s nasty. It can also be used to steal data and to perform denial of service attacks.
How it works
Some applications, especially those that expose SOAP web services, accept XML documents that drive functionality. XML processors are needed to parse the XML and find out what operation the client wants to perform.
XML processors are interpreters. XXE tricks these processors into including external URIs and then executing their contents. Similar to injection vulnerabilities, XXE can cause an attacker’s code to be executed by your application.
I’m sure this feature was thought of as useful at the time, but now it’s seen as quite dangerous.
For example, you can steal a local file by sending along an XML file like so:
1
2
3
4
5
|
<? xml version = "1.0" encoding = "ISO-8859-1" ?> <! DOCTYPE foo [ <!ELEMENT foo ANY > < foo >&xxe;</ foo > |
When this XML file is sent to a vulnerable application, the response will contain the contents of the etc/passwd file.
A famous XXE attack is the billion laughs attack, which takes up all of your server’s memory and crashes it.
How you can help
Patch your XML processors. Stop using XML and use JSON instead. That’s pretty much it.
This vulnerability was discovered several years ago and most XML processor libraries have patched themselves to protect against it. They did this by turning external entity processing off by default.
Be wary of the “NOENT” option within XML parsing libraries. This actually indicates that the processor should substitute entities, which is the root of XXE attacks. Despite its confusing name, if set to true, you could open up yourself to XXE attacks and not even know it.
You can use JSON to transfer data around and avoid XML altogether. JSON isn’t a full-proof solution against attack, but it’s not susceptible to XXE.
If you have to use external entities, validate the entities coming in against a whitelist or using XSD validation. And test for this vulnerability on a regular basis by uploading a malicious XML file to your site. This can be automated to make it easier on your team.
XXE is a vulnerability that can be eliminated from this list with your help. It’s on the list because not many people knew about it. Now that you do, work to get rid of it.
OWASP Top 10 2017 – 5: Broken Access Control
On the last Top 10 list, two risks were associated to access control, Insecure Direct Object References and Missing Function Level Access Control. These two have been merged into Broken Access Control.
How it works
Access control is all about giving the appropriate access to the appropriate users. When access control is broken, attackers can perform functions and see data that they are not authorized to see.
Let’s imagine your software stores medical records. A user logs in to view their personal medical history. As a nice feature, you’ve included the ability to generate a PDF file for them to download.
When they click the download button for the PDF, it is opened in the browser. The user notices the customerId query parameter in the URL. The change the customerId and refresh the page.
All of a sudden, a PDF of a complete stranger’s medical history pops up. Ouch.
That is what broken access control is all about. It could be data or functionality.
How you can help
Access control can be tricky. However, a shift in mindset can help developers to get the right idea.
Deny, deny, deny.
The default answer to anyone asking to do something should be “No.” Default deny means that you tell the system only the people that are allowed to access a feature. Anyone else is denied access.
Also, make sure you’re using record-level access. In the above example, this is missing. When I am logged in to a system, I should only have access to the records that I own. I shouldn’t have access to the entire database just because I am logged in.
Don’t forget about servers. Directory traversal attacks occur when an attacker can access restricted directories in a server using a web browser. This attack can only occur when the webserver is given access to server directories outside of its own. There’s simply no reason for that.
Here are some other quick tips on how to prevent this problem:
- Log access control errors and raise alarms when they pile up
- Check the permissions of every component of your application
- Apply permissions to specific records instead of allowing access to all records
- Invalidate tokens when the user logs out
We can take broken access control down a peg by being smart about what our application and its users can do. Pay attention to who needs to do what. Keep your customers’ data safe.
This is part one of a two-part series: continue on to Part Two to cover the rest of the Top 10!