The use of APIs is now ubiquitous, and the “API economy” is well and truly established. From cloud-based services, back-end services for mobile apps, internal server-to-server services, microservices and even AJAX-based web front-ends, APIs connect and rule.
As a result, and especially with the online exposure of online banking and other financial services, APIs are increasingly becoming targets for cybercriminals.
This article focuses on APIs exposed to external clients over HTTP using REST-type protocols. (It is assumed that HTTPS is the actual protocol used for all exposed REST APIs.)
API scope considerations
Before delving into the details, you should examine the scope of your API use, as this will influence the security requirements.
Scope considerations include:
- Is your API designed for access by a specific client type (e.g., mobile app) or for more general use from a variety of client types?
- Is personal or sensitive data to be exposed? This requires, at a minimum, strong authentication and authorization mechanisms
- Are the APIs accessible only by internal systems? You must assume that even here, the same authentication principles apply as for externally exposed services
- For high security, consider splitting your API between an exposed front-end service and non-exposed servers, with the real API functionality on the non-exposed servers. Use encrypted secure communication between the two parts
API security considerations and tips
As an API provider, you should consider at minimum the following areas in API security:
- Rate limiting
This is identification of the API caller. In some cases, authentication is not required; for example, this applies to some public information services, such as weather reports. However, authentication is a requirement in most cases, especially when personal or sensitive data is involved.
The following methods are in common use:
- An access key
- An access token
- Client certificate (common for internal APIs not directly exposed.)
The method used to authenticate the API caller will generally be determined by the security requirements of the service involved.
The practice of sending credentials with each API request (basic access authentication) is certainly not recommended. This unnecessarily exposes the credentials in the traffic, endpoints and, possibly, in source code by lazy developers.
Use of access keys issued by the API service is a simple method, appropriate for low-level security applications. In use, the API service issues the key (which usually resembles a random sequence of characters) for each client registered to use the API. The API caller then includes this key in the header for all API calls, which the API service verifies. Callers can improve the security of this method by requesting a new key at regular intervals.
A better method is to use the OAuth2 protocol for authentication. Access tokens issued to clients can be time-limited and revoked, to minimize the chance of unauthorized use. In the case of APIs that release personal or sensitive data, an interactive login with the user must be used, using appropriate OAuth2 or OIDC flows; at the same time, the user can consent to release of some or all of the requested data. This point will be discussed later under Authorization. The use of access tokens also facilitates stateless, highly scalable operation of your APIs.
2. API usage from native and mobile apps
These use cases are especially problematic, as it is not possible to prevent hackers from discovering embedded secrets, signatures or to monitor traffic to discover data transferred during security handshakes. Therefore, for any personal or sensitive data, an interactive login with the user must be used at the provider. An access token may then be released to authorize subsequent data access by the app.
The Proof Key for Code Exchange (PKCE) flow is designed specifically to secure OAuth2/OIDC with native or mobile apps.
Authorization (explicit permission to access APIs or data) becomes important where you are either providing groups of related API functions or when personal or sensitive data is involved.
To provide for manageable authorization requires the use of access tokens. This in turn generally means using OAuth2 or OIDC to issue them, depending on your requirements.
Use of access tokens means that granting access to APIs or specific data simply involves examining the permission set in the token, affording highly-scalable stateless operation.
4. Bearer tokens
A bearer access token is one that may be used by whoever possesses it. Although they are adequate for most purposes, bearer tokens may be considered insecure for higher-security applications. In these cases, digital signatures may be employed to verify the user.
In any IT system, auditing is a key tool for security. For APIs, it is therefore vital to ensure that events are well-audited, and that your audit management system is configured to present alerts to system administrators in the event of unusual events. For example, you should be alerted to repeated authentication failures within given time frames, as this might indicate a concerted attack is in progress.
Audit of consent to release personal data is particularly important, and you may want this to be stored separately (with events timestamped and digitally signed) in case of disputes. To avoid data leaks and comply with regulations such as GDPR, ensure that personal or sensitive data never ends up in audit logs.
One common product of naive API development is error responses that carry sensitive data. Ensure that your error responses do not expose any information about the internal architecture or state of your back-end system, such as raw database error messages, as these may be exploitable by hackers. Instead, return general error responses to your API callers and rely on your audit logs to help you determine exact faults. Similarly, ensure that you never leak personal information in error responses.
Another aspect of API response is data privacy; in most cases, TLS encryption of data release in responses is considered sufficient. However, personal or sensitive data should be encrypted with client keys, so that privacy is maintained even if the data goes astray.
To ensure that API responses go to the correct client, it is good practice to ensure that responses are only returned to URLs that are preset for each client. This minimizes the unauthorized use of keys, access codes or tokens and is easy to set up when the client registers for keys or access credentials.
8. Rate limiting
Rate limiting or throttling of APIs is commonly used to maintain API performance and help prevent denial-of-service attacks; in addition, it can help segregate between different levels of service: for example, free API access may be severely rate limited, whereas paid for access will have a higher rate applied. Rate limiting is normally based on a per client (key or access token) basis.
Rate limiting may be made on the basis of the maximum number of requests in a given time period or the minimum time between requests. The latter is often used for APIs that involve polling.
When rate limiting is implemented, it is sensible to return errors to the client that indicate when then next access can be made or a reminder of the time interval.
In our hyperconnected world, APIs offer a very powerful mechanism of connecting data across disparate systems. This makes the API a perfect target for cybercriminals. API development must sit alongside robust security measures during the API development and when it is implemented and used.
The top six tips provided here will ensure you use best practices in protecting your API use, giving you the foundation for a secure and privacy-respectful service.
- Cross-Origin Resource Sharing (CORS), developer.mozilla.org
- OAuth 2.0, oauth.net
- Welcome to OpenID Connect, OpenID
- Proof Key for Code Exchange by OAuth Public Clients, tools.ietf.org