APIs are where you protect data, and this is the best place to start when thinking about exploits. Typically, API access involves three types of components. An Authorization Server is hosted alongside APIs and issues tokens to clients. A Client sends access tokens to the API, which then uses them to apply domain-specific authorization rules.

This article focuses on common OAuth vulnerabilities when developing and hosting APIs, along with some mitigations to improve security.

1. Leaked Tokens

There are a couple of basic things that companies building APIs should always get right:

Access tokens must not be sent in URLs, such as via query parameters, since they may then be recorded in HTTP server logs, which could be exploited.

Also, aim to avoid building your own back-end token stores, which then need to be protected. Instead, let the Authorization Server manage token storage for you.

2. Weak Access Token Validation

APIs must digitally verify JWTs on every request, and the most common solution for this is via an asymmetric public key downloaded from the Authorization Server. There are many respected security libraries in various technologies that can be used to do low-level cryptography.

A known vulnerability is for an attacker to send a JWT with a null algorithm in the JWT header, possibly enabling them to tamper with tokens they send:

  • alg:none

Instead of accepting this, the API must specify the algorithms it trusts and use a secure value such as RS256 or ES256. The following generic details must also be verified to ensure that they have valid values:

  • Issuer: This must match the value of the Authorization Server.
  • Expiry: The current time must be between the token’s nbf and exp values.
  • Audience: This represents a set of one or more related APIs.

If these checks are not made correctly, then there are opportunities for exploits, though any good JWT validation library should make the proper processing easy.

3. Insufficient Scopes

OAuth scopes are high-level permissions to control the areas of data a token can access and what operations can be performed on that data, as in these examples:

  • orders_write
  • inventory_read

Scopes provide another level of defense so that you do not rely solely on API code to perform authorization correctly. If an all-encompassing scope such as all or default is used, this enables an attacker to attempt to use an access token against all API endpoints.

Use scopes to enable coarse-grained access. Middleware such as a reverse proxy can then reject obviously invalid requests sent by an attacker. This can also save costs in some setups.

4. Unverified Claims

Important security-related values like those below should be included as claims in JWTs sent to APIs, where they act as values asserted by the Authorization Server. Once the API digitally verifies the JWT, it can then trust these values and use them for authorization:

  • User ID = 27890345
  • Company ID = 890234
  • Role = superuser
  • Scope = openid profile payment

Do not receive these values in APIs via URL path segments, query parameters, or HTTP headers, where they are unverifiable, since this enables exploits where an attacker can change the input and potentially gain unauthorized access.

5. Leaked Private Data

Although APIs need claims for authorization, details should not be leaked to internet clients, which should instead use opaque access tokens that do not reveal any confidential details.

This is best managed by placing a reverse proxy in front of APIs and using it to deal with exchanging tokens, as covered in this Curity article on the Phantom Token Pattern:

  • Authorization Server saves details of claims issued.
  • Authorization Server issues access tokens to internet clients in a reference token format.
  • Client sends reference token through the reverse proxy to APIs.
  • The reverse proxy introspects received access tokens to get claims into a JWT.
  • The reverse proxy forwards the JWT to APIs.
  • APIs digitally verifies the JWT and use its claims for authorization.

6. Broken Object Level Authorization

It is essential that companies developing APIs can control the claims issued in JWTs so that they can perform their domain-specific authorization. This is usually based on rules related to data ownership:

  • A patient must only be able to see their own medical record.
  • A doctor must only be able to see patient records for particular surgeries.
  • A customer must only be able to see products for their subscription level.

Your own app may only ever send requests based on the currently logged-in user’s ID, but an attacker could send API requests via tools such as curl and change IDs to those of other users.

Ensure that JWTs delivered to APIs contain the claims needed. This will usually require the ability of the Authorization Server to read domain-specific claims at the time of token issuance.

7. Weak API Infrastructure Design

When designing hosting, it is recommended to avoid exposing servers that access data sources directly to the internet. Instead, a reverse proxy should be placed in front of them so that if an attacker breaches the first layer, they cannot access data sources.

Another decision is deciding which APIs can be reached by internet clients. If all microservices are exposed, then the attack surface is greater. This leads some companies to categorize APIs and use networking to only expose Internet APIs as opposed to core microservices.

8. Weak Microservices Security

The above type of infrastructure setup can then lead to cutting security corners in microservices:

  • Internet APIs validate JWTs correctly.
  • Internet APIs then pass claims in headers to core microservices.

Avoid this since it is vulnerable to Man in the Middle (MITM) exploits. Instead, use a zero trust approach, where all APIs validate access tokens on every request:

  • In memory, JWT validation is fast and designed to scale.
  • Access tokens can usually be forwarded directly between microservices.

All APIs then operate securely using verifiable claims, and attackers must get hold of a valid JWT before they can call any of your APIs.

9. Insufficient Logging

Access to sensitive data should also be audited, and this is an area where Identity and Access Management (IAM) systems can do much of the work for you:

  • Use the Authorization Server to record details of which claims and scopes were issued and for which clients and users.
  • Store Personally Identifiable Information (PII) in the Authorization Server so that user consent can be easily integrated and changes to users are audited.
  • Consider the use of an Entitlement Management System that provides additional auditing during API requests

Conclusion

Designing a secure back end to your software platform requires insight, but by following OAuth’s design patterns, you can manage API security at scale, with only simple code. For additional related resources, check out the OWASP Top 10 API Vulnerabilities and our post on Top OAuth Client Vulnerabilities.