28 October 2022
API security threats - TSH’s work with the OWASP top 10
Cybersecurity is not only about ensuring the security of web applications, but also providing it to mobile applications or API. Why API? In order to make the styling, UX, and performance perfect, you can’t forget about API – the application that will communicate with our backend. The safety of the backend is crucial to your app’s safety, function, and your users’ sensitive data. The attacker will not only focus on clients (web app, mobile app, sensors, etc.) but will look deeper into the vulnerability.
A very popular SQL injection vulnerability is strictly related to data manipulation in a database. It’s a preventable vulnerability.
An example is the broken API Authorization vulnerability that was found in a friendly way by Omkar Bhagwat (th3_hidd3n_mist). This vulnerability made it possible to delete, take over or learn the sensitive data of thousands of subdomains without interacting with the user.
Now that you know you want this and need this in your project, let’s take a look at API security tests (an application that is used to communicate with other applications/devices on the backend). It’s worth noting that the OWASP (Open Web Application Security Project) organization 2019 prepared a ranking of the 10 most common API vulnerabilities, called API Security Top 10 2019.
The project updates data every few years, and so will we – once OWASP publishes again, probably sometime in 2023.
API security and types of projects
Ensuring API security is important because it may not only apply to one device, but it has the ability to connect to several, e.g. sensors, telephone, web applications, cars, and TV.
A ton of vulnerabilities are easy to check for – ensuring they’re covered should always be in your project plan. I am a fan of the OWASP organization, and I based my examples of fighting with vulnerabilities on their research.
API Security Top 10, similar to the OWASP Top 10 report for web applications, includes the 10 most common vulnerabilities like
- Broken Object Level Authorization,
- Broken User Authentication,
- Excessive Data Exposure,
- Lack of Resources & Rate Limiting,
- Broken Function Level Authorization,
- Mass Assignment,
- Security Misconfiguration,
- Injection,
- Improper Assets Management,
- Insufficient Logging & Monitoring.
An interesting fact is that 6 out of 10 of the API vulnerabilities are identical to known web application vulnerabilities.
It is worth noting that
- A1. Broken Object Level Authorization is the same as the web-based Insecure Direct Object Reference,
- A2. Broken User Authentication with web-based Broken Authentication and Session Management
- A3 Excessive Data Exposure with web-based Sensitive Data Exposure.
From the known vulnerabilities from the OWASP Top 10, we can also distinguish A7. Security Misconfiguration, A8. Injection and A10. Insufficient Logging & Monitoring, as shown in my table below.
Year the web app vulnerability was published in the OWASP top 10 | 2003 | 2004 | 2007 | 2010 | 2013 | 2017 | 2021 |
API vulnerability | |||||||
A1. Broken Object Level Authorization | A4 | A4 | A4 | ||||
A2. Broken User Authentication | A3 | A3 | A7 | A3 | A2 | A2 | |
A3. Excessive Data Exposure | A6 | A3 | |||||
A4. Lack of Resources & Rate Limiting | |||||||
A5. Broken Function Level Authorization | |||||||
A6. Mass Assignment | |||||||
A7. Security Misconfiguration | A6 | A5 | A6 | A5 | |||
A8. Injection | A6 | A6 | A2 | A1 | A1 | A1 | A3 |
A9. Improper Assets Management | |||||||
A10. Insufficient Logging & Monitoring | A10 |
Check out my previous article on security threats spotted by QA engineers – cybersecurity testing based on our very own TSH projects! It contains a lot of additional knowledge and research that compliments API security – so get the big picture. I’d like to show you how you can easily ensure quality and security in line with the problems listed in API Security Top 10 2019 just like I did in the last article.
Of course, all examples are based on my current projects, so not every criterion will be tested, and not every success show me a vulnerability ;).
Let’s begin at the beginning
“Begin at the beginning,” the King said, very gravely, “and go on till you come to the end: then stop.” – Lewis Carrol, Alice in Wonderland
Yes – let’s be methodical. I have put all of my examples in the order of OWASP API vulnerabilities, going from beginning to end. This will help you find the vulnerability that interests you and how I solved the problem when working on my own projects.
As a reminder, here there are in order, just like they appear in the sections below:
- A1. Broken Object Level Authorization
- A2. Broken User Authentication
- A3. Excessive Data Exposure
- A4. Lack of Resources & Rate Limiting
- A5. Broken Function Level Authorization
- A6. Mass Assignment
- A7. Security Misconfiguration
- A8. Injection
- A9. Improper Assets Management
- A10. Insufficient Logging & Monitoring
Remember that these top 10 vulnerabilities outlined by OWASP aren’t the only ones you should be worried about – but they are the top 10 most critical vulnerabilities that every project should take into account. Without further ado:
Paranoid about API vulnerabilities in your project?
Knowledge is power – and our QA team has the power!
A2. Broken User Authentication
Broken User Authentication is closely related to password management (it allows the use of default or weak passwords, the use of ineffective password recovery processes, no password hashing, etc.).
It also allows for automated attacks such as credential stuffing (when the attacker has a list of valid usernames and passwords), brute force, or other automatic attacks.
An example is a lack of logging out the user after a specified time (often in banking applications this counter is set to 10 minutes of inactivity of the application).
In our applications it is usually after 5 minutes – the web application checks whether the token is active, otherwise, the endpoint returns the value “Unauthenticated” and logs out the user after a long idle time.
When logging in to our applications, only what we get in response is the last 3 digits of the phone number to which the OTP code is sent. This discovery makes me proud because I cannot see redundant data.
Then, after entering the 4-digit OTP code, we are shown a series of data about the user, i.e. his account-id, user-id, e-mail, and phone number, which are necessary for the authentication process, and the phone number is 2FA (this on him comes the OTP code entered by the user).
In addition, the states displayed, under which the user type is located. It is worth noting that the user’s password is not provided in any of the requests, which unfortunately happens in some applications.
Let’s move on to the next vulnerability – Excessive Data Exposure!
A3. Excessive Data Exposure
Due to this vulnerability, the API can return sensitive data in its responses, which are filtered only on the client side.
In the API, we can see a list of data that is not displayed on the UI side. It is worth remembering that the responses in the API should contain only legitimate data and replace the general methods (i.e. to_string) with specific properties.
Additionally, you can implement a response validation mechanism in which you must define the data returned by all API methods, including errors.
A perfect example is one of the websites that display only a few basic information about the owner of the company on the UI side, ie Name, National ID, Nationality, Gender, Mobile and Email.
Unfortunately, on the API side, we display a lot more information that we do not need on the web application side, namely details about the main company of this contact and his private address.
A4. Lack of Resources & Rate Limiting
The API is also vulnerable to attacks when one of the following limits is not set: Execution timeouts, Max allocable memory, Number of file descriptors, Number of processes, Request payload size, Number of requests per client/resource, Number of records per page to return in a single request-response, Example Attack Scenarios.
One of my websites is a representative, where we can view up to 100 employees on the site. The user list is retrieved from the server with the following query: / API / users? Page = 1 & size = 100. An attacker by changing the size parameter to, for example, 200,000 (if there are so many or more records), can cause database performance problems.
Meanwhile, the API stops responding and is unable to handle any further requests.
On our stage, I found a user with 3409 employees.
I wanted to display them all at once, but after a long wait, I got a “Gateway Time-out” response by manipulating the page perimeter.
To illustrate the problem (when reporting a bug) I presented this problem on the UI side. In the URL bar, I changed it from page=100
to page=4000
.
As you can see, the application tries to hit the same endpoint several times. The waiting time for a response to one query is about 1 minute, and then receive a code with the 504 status. The application itself makes 4 attempts.
After the last one, the user receives the message “Something went wrong. Please try again later. ”. Of course, by refreshing the page, the application tries to hit the endpoint 4 times and each time receives a timeout in response.
In the event of a massive attack, I dare say that the application will crash ;).
A6. Mass Assignment
When we include many properties in objects, and some of them are updated by the client, the endpoint API becomes vulnerable if it automatically converts client parameters to object properties without taking into account the level of exposure and sensitivity of the property. Some of them should be set only by administrators, i.e. whether the user is an administrator (“is_admin”: “true”;), and process-dependent properties should be set only after their prior verification.
To be on the safe side, create a whitelist with properties that the client can update and a blacklist with properties that should not be available to clients. All schemas and endpoint inputs should be explicitly defined and enforced. You should also avoid functions that automatically bind client input into code variables or internal objects.
An example would be file upload. After successfully adding the file, it is saved in binary format and given the UUID.
The result is a string that is not directly used by the application. To download a file, the application first checks the user’s permissions, whether the user has the request to which the file is assigned, and in the last step, allows it to be downloaded (if these assumptions are met). From the API side, you cannot download this file directly from one endpoint.
A7. Security Misconfiguration
This vulnerability, as in the web OWASP top 10, consists of improperly configured permissions, the lack of the latest security patches, security in the transport layer (TLS), or simply the use of outdated software. It may also be caused by an improperly defined or missing CORS (Cross-Origin Resource Sharing) policy. Likewise, error messages can contain redundant data.
It is not possible to show redundant data on our websites on the UI side. Usually, we only display a specific error description along with its id (to make it easier to find the cause in the logs). Unfortunately, we display redundant information on the API side of the stage environment. It is a consolation that there are no such mishaps in the production environment ;).
A8. Injection
The vulnerability occurs when data provided by the client or from external (integrated) systems is not filtered, validated, or cleaned by API in any way, but directly used or combined with SQL / NoSQL / LDAP queries, XML parsers, OS commands, etc.
To prevent Injection, separate commands from queries, and establish data validation using a trusted and maintained library. Special characters should be written descriptively (eg, “&” as “& amp;” and “<” as “& lt;”), and the number of records should be limited.
To begin with, I wanted to check if there are Cross-Site Scripting (XSS) attacks, which, according to the latest web OWASP Top 10, have been combined into one vulnerability with Injection. As in the previous article, Reflected XSS went first. Out of curiosity, I tried to parse a URL request from:
/api/laborer?perPage=100&page=1
to:
/api/laborer?perPage=<script>alert(XSS)</script> \
To display a pop-up window with the text “XSS” (this is one of the flagship ways to detect this vulnerability).
API answered me with code 500 – Internal Server Error and displayed information about the wrong data type
“Cannot assign string to property App \\ Http \\ Requests \\ GetLaborers \\ DTO \\ FormRequestDTO :: $ perPage of type int”
Similarly, I wanted to test if there is Stored (Persistent) XSS, i.e. saving the XSS code as one of the parameters in the database.
In the screenshot above you can see that the location has been added correctly. Fortunately, API security treats XSS code as a string and does not load it.
To show that XSS definitely does not appear in the web application, I did it in parallel. The location has appeared in the list of locations and no alert has been displayed. In the location details, in the description field, you can notice an added, broken script.
Injection vulnerability is not only XSSy, but most of all SQL injection, PHP Injection, etc. And as in almost every tutorial, to check SQL Injection vulnerability, I wanted to investigate whether the user may fail to provide a password or login using SQL code, which is always true or is the beginning of a comment:
In both cases, I got the answer “sign-in login or password incorrect” with the code 422 – Unprocessable Entity.
It is known that the above examples are not determinants of whether the vulnerability of SQL Injection occurs, but are only intended to show the technique. It is worth trying, opening up to tests, and trying again (changing parameters or names). As I mentioned in the previous article, the admin name does not have to be admin but can consist of a string of numbers, etc.
A9. Improper Assets Management
This vulnerability occurs when the documentation is not updated or missing. When there is no integrated services inventory, host inventory, etc., or they are out of date.
When there is no clear information on what environment the API is running on (stage, UAT, development, prod, etc.), who should have access to it and which version is running? Failure to update such information or its complete absence has great consequences. For example, the attacker, knowing the vulnerability of the older API version, may try to reproduce this bug on the newer version.
To prevent this from happening, create documentation that will be regularly updated. It should contain a list of all hosts, information about environments, accesses, and API versions. And above all, it is worth remembering that API documentation should be made available only to those authorized to use the API.
The documentation on our websites is relatively up-to-date. It is on this basis that frontend developers write a web application, and our backend is a link and additional protection between the web application and the API.
A10. Insufficient Logging & Monitoring
The vulnerability occurs when no logs are generated or their integrity is not ensured. And when the API infrastructure and logs are not constantly monitored.
This vulnerability does not occur in our applications, as we have several different tools to collect information about what is happening in the applications. Of course, we do not store sensitive or even redundant data. In each tool, we have custom dashboards, thanks to which we aggregate information and are able to quickly indicate where and when the problem began.
It may be a good practice to integrate a tool such as Airbrake (collecting errors generated by applications and aggregating results) with Slack or other communicators used by everyone at work, where everyone interested will have information about the incident on a regular basis.
Be prepared!
In conclusion, testing the API for security is not as difficult as it might seem, and it is extremely important.
There are situations when security problems are only patched on the client side, and using the API alone, we are able to recreate them. By exposing the API, we expose a number of other applications / IoT that use it. Therefore, we should start with ensuring API security to fix any imperfections on the side of the final applications. It should be remembered that application security is not only security on the client’s side.
I hope that the article will inspire someone to at least try to identify a few vulnerabilities, to find out that security testing is not so scary and difficult, and above all, to ensure the security of the application. And I hope it inspires businesses to create safer, less vulnerable apps – you need some vulnerability in your life, but nowhere near where the business of making applications is concerned.