OWASP Top 10 API Security Problems
05.10.2020, Christian Mäder

The OWASP collects and categorizes typical security problems in web software. In late 2019 – for the first time – they released a guide to the most typical issues found in web APIs. This blog post provides a summary of each of the 10 issues.

When designing modern software, APIs are becoming ever more important. Single page web applications, which are often encountered in the B2B and enterprise world and which are often made with technologies such as Angular or VueJS, heavily rely on web APIs. That’s why we increasingly concern ourselves with securing such – and other – APIs.

Issue 1: Broken Object Level Authorization

In a typical API call, a certain resource is requested from another service, or actions (e.g. modification) shall be performed by the service on that resource. Every such resource provider should verify that the user, who is interacting with that certain resource, is actually allowed to do so.

For example, in a service that is used by multiple users, each user may access the data of its profile via /user/{userId}. So the user with a userId of 11 can get information about itself by calling /user/11. But it should not be possible to get information about any other user, e.g. /user/12 should return an error for a request issued by the user with the userId 11.

Sometimes services don’t actually perform authorization checks on a single resource (such as /user/*) and thereby permit any request as long as the requestor is authenticated. I.e. as long as I am signed in as user 11, I would be able to access all data of that resource, not just the single object I’m supposed to see. This should not be the case and this is what this first issue describes.

See Issue 5 below for a similar issue.

Issue 2: Broken User Authentication

Often only authenticated users are allowed to access certain API endpoints. Therefore a user who is calling such an API has to authenticate itself. This second issue describes typical scenarios when a service does not implement mechanisms to prevent common attacks on the authentication-part of the service.

Common weaknesses that are often exploited by attackers include:

  • If an attacker possesses a list of valid credentials (e.g. username + password) from some other service (e.g. because of a leak at another company) and tries all these combinations, then there should be restrictions in place to prevent this attacker from endlessly trying these credentials. I.e. a single client should only be allowed try a limited amount of combinations per timespan. Another counter-measure is to require a second factor during the authentication process. The described attack is commonly called Credential Stuffing.
  • The classical brute force attack, where an attacker just randomly tries credentials, is a pretty old attack, which is very simple to implement for a moderately skilled attacker. This attack can be prevented by locking a specific user account for a certain amount of time after a certain amount of failed authentication attempts, but also by requiring multi-factor authentication.
  • When there are no rules for strong passwords, i.e. a minimum length requirement or a check for exposed credentials (e.g. by using the Have I Been Pwned API), passwords tend to be short and can be brute-forced quicker.
  • Having sensitive information in the URL, such as a password or API key, should be avoided. This is because such information will end up being saved in applications, e.g. in the browsing history of your web browser or the command history in your Terminal, e.g. when using cURL.
  • When the backend does not verify whether a given authentication token is still valid, then an invalidated or old token can be re-used by an adversary. E.g. an authentication token of a user, that has already logged out but who’s temporal validity is otherwise valid, should not be usable to perform any actions anymore. This can be prevented by constantly validating all authentication tokens, i.e. calling the authentication service and have it confirm the validity of all authentication tokens.
  • When the backend allows weak authentication tokens, such as non-signed tokens or such that are signed with a weak algorithm (e.g. SHA-1), then such credentials can be constructed by adversaries.
  • When unencrypted credentials are sent over an unencrypted connection, then they can be intercepted and used by attackers.

A similar example is that the HTTP Header X-Forwarded-For is sometimes not stripped when a request arrives at the edge of a datacenter. Sometimes the content of this is used to apply different security rules, e.g. IP-based authorization. So if such security relevant headers, that are meant for internal use, are not stripped on the edge of your perimeter, then an attacker can use them to circumvent your security measures.

Issue 3: Excessive Data Exposure

The third issue describes that the backend accidentally provides more information than necessary. For example, when the backend of a dating app sends the exact coordinates of dating candidates to the client, but the client only needs the coarse location to determine the distance, then too much information is made available to the client. An adversary may get more information than should actually be made available, this often includes Personally Identifiable Information (PII) data about other users. In that specific case, the backend should have sent just the course location.

Issue 4: Lack of Resources & Rate Limiting

As all requests, API requests consume resources on the server side. Consumed resources somehow always turn into money which the provider of a service needs to spend to operate that service.

It’s therefore in a provider’s self-interest to protect against excessive use of its API. Even if customers are charged per request, it may be wise to protect customers from excessive requests. Such excessive requests easily happen by accident, e.g. when a script is modified in a way such it accidentally doesn’t stop sending requests and nobody notices.

Things to look out for:

  • Setting an execution timeout, which prevents that compute resources are busy processing a certain request for an excessive period.
  • Limiting the size of payloads that your API accepts per request.
  • Limiting the total number of requests per client or per resource during a certain interval, e.g. limiting to 120 requests per minute (per user or per resource or even a combination of both).
  • Limiting the size of your responses. This is usually done by implementing paging, i.e. returning only a certain amount of all the available records per request.
  • Setting the maximum allocable memory, which prevents that a single request uses an excessive amount of memory.
  • Limiting the number of file descriptors that are available to each request to prevent that other requests can’t open new files.
  • Limiting the number of processes that are available to each request to prevent that other requests can’t start their processes.

Some of these limits are pretty straight-forward to define using container technology such as Docker and/or Kubernetes. Others require configurations in your API gateway or service mesh software. And some need to be implemented directly in your application’s code.

Issue 5: Broken Function Level Authorization

This issue describes that each user should only have access to the API endpoints for which this user is authorized. Often this concerns administrative API endpoints. For example, the regular user with the user-id 11 may fetch it’s profile /user/11, but it should not be possible to access the /users endpoint that would list all users.

This issue is very similar to Issue 1 above, but there’s a tiny difference. This issue concerns itself with access to different endpoints, i.e. /users vs. /user/11. Whereas Issue 1‘s concern is about accessing a different resource on the same endpoint, i.e. /users/11 vs. /users/12.

Issue 6: Mass Assignment

The concern of this issue is that a user may update properties on resources, which it should not be allowed to update.

For example, in most applications all users have a unique ID. And while users may be allowed update their email address, they should not be allowed modify their ID.

Issue 7: Security Misconfiguration

In this issue, common software and web security problems are addressed. The list includes:

  • Security patches (on any level, i.e. operating system, software runtime, software framework, API gateway) are missing.
  • Features, that are not needed, are enabled. A famous example is directory listing in Apache HTTPD.
  • There is no appropriate transport layer security (e.g. TLS or DTLS) or it is badly configured (e.g. TLS 1.1 and older are still allowed).
  • Security features are not used (e.g. Security Headers in HTTP or they are misconfigured. Such an example may be a bad Cross-Origin Resource Sharing (CORS) policy.
  • Sensitive internal data is exposed to an adversary in the form of log files, stack traces and other error messages.

Issue 8: Injection

The concern of this issue is that data from users should never be trusted and always be appropriately escaped. Famous injections are SQL injections, OS command injections, but also HTML injections (i.e. Cross Site Scripting, XSS). Such injections might happen on the path from the user to the server, but also on the way from the sever to the client and even in-between servers. Malicious data may not only come from your customers, but actually from any outside source. For example a third party provider of yours could return bad data as well.

Examples are:

  • When writing to the database, the SQL statement is modified because the username is not properly escaped.
  • When rendering data in the browser, JavaScript might be written to the page accidentally because it is not escaped.
  • When converting data to a JSON object to call a third party service, it’s structure is modified because data in it is not properly escaped.
  • The HTTP Header X-Forwarded-For is not stripped when it arrives in your datacenter and it’s content is passed to an OS-script as a parameter.

Issue 9: Improper Assets Management

This is more of an organizational issue. Which makes it even harder to remedy.

It describes, that an organization does not have a complete overview over what (versions of) APIs are currently running or how they are actually protected.

An example from the original OWASP document is that a certain API may be available and well protected on myservice.example/api, but there is also a development version running on beta.myservice.example/api. The development version is not protected by the same anti-bruteforce gateway, but has – for development purposes – access to some of the same data, as that data is imported from production to the development database from time to time. An attacker might use that API to brute-force access to a certain user-account, which is then valid on the actual service.

Issue 10: Insufficient Logging & Monitoring

In my experience, this issue usually occurs when operating the API is just concerned as a by-product, i.e. something with which the development teams concerns itself only just before the release date, i.e. development team was not forced to include (or at least talk to) operations personell early in the development phase.

Logfiles are core to figure out what happened. They are essential during debugging, but are also key when figuring out what happened in case of an imminent or past attack. Incorrectly configured logging, e.g. when the log level is set to TRACE, can also create opportunities for denial of service attacks, as a disk might run full if an attacker issues a large amount of requests. Also the IO operations required to write the logs may prevent actual data from being accessed on a disk.

Final Thoughts

Most of these issues do not happen on purpose and preventing them is just common sense. But it’s only common sense to prevent them when the developers are aware of such issues. We are aware of them.

I highly recommend to also skim through the original document. It contains more relevant examples that showcase each issue and can be downloaded from the respective GitHub repository for free.