API security threats - TSH’s work with the OWASP top 10

api security
By Piotr Baran

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 AuthorizationA4A4A4
A2. Broken User AuthenticationA3A3A7A3A2A2
A3. Excessive Data ExposureA6A3
A4. Lack of Resources & Rate Limiting
A5. Broken Function Level Authorization
A6. Mass Assignment
A7. Security MisconfigurationA6A5A6A5
A8. InjectionA6A6A2A1A1A1A3
A9. Improper Assets Management
A10. Insufficient Logging & MonitoringA10

 

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!

A1. Broken Object Level Authorization

secure apis and apis expose application logic web api security

 

Broken Object Level Authorization is very similar to the web-based IDOR (Insecure Direct Object References) vulnerability, which was in the 4th position in the ranking from 2007-2013. 

It consists of the possibility of getting into the object by manipulating its parameters. An example is the replacement of the request ID number, e.g. from 1 to 2, to get to the content of request 2. 

It may happen, like OWASP Top 10: 2021 A1 Broken Access Control, when by manipulating the parameters, we get a response that is not allowed for our user, for example for a user with higher privileges.

In the example of one of my projects, I would like to show that the user has access only to requests with ID: 17778, 17777, 17771…

web app security

After manipulating the parameters, I was able to view the details of the request from outside of its list (i.e. another user’s request) with id = 1-17793:

api security

At this point, it turned out that the lack of the requestor object allows us to display all requests (regardless of who created it), i.e. access to unauthorized data.

Following the blow, I wanted to check if user A had the ability to view user B’s company data. Therefore, after successfully logging in, I replaced the company ID in the PATCH.

As you can see in the picture below, the API has been secured against this eventuality and returns the error code 403 and the information, “Forbidden by Project Gateway”.

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 ;).

A5. Broken Function Level Authorization

This vulnerability consists in finding authorization problems. Among other things, it should be checked whether the user with lower privileges has access to the endpoints of the user with higher privileges or whether he can perform actions to which he should not have access (e.g. by changing the method from GET to DELETE). 

Can the user with A privileges access the user functions with B privileges by modifying the endpoint URL with its parameters?

On our websites, each logged-in user has access to the common part of the application, only after redirecting to a specific module, the authorized user should gain access to it, otherwise, they should receive information that he does not have such rights. On the API side, the user only gets the error code 401 – Unautorized with no redundant data.

Fortunately, the method change protection is implemented in our solutions. The response we get is 422 – Method Not Allowed and the response is “The DELETE method is not supported for this route. Supported methods: GET, HEAD. ” as shown in the screenshot below.

 

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.

Impressed with our knowledge?

Make it work for you!

You may also like

Webinar - Scaling development

[Dec 8] Learn how 220+ clients beat talent shortages. From our Business Partner, Marcin Mazurek.

Free registration

What would you like to do?

    This site is protected by reCAPTCHA and the Google
    Privacy Policy and Terms of Service apply.

    We regard the TSH team as co-founders in our business. The entire team from The Software House has invested an incredible amount of time to truly understand our business, our users and their needs.

    Eyass Shakrah

    Co-Founder of Pet Media Group

    Thanks

    Thank you for your inquiry!

    We'll be back to you shortly to discuss your needs in more detail.