How to secure REST API: Best practices and tips

secure rest api

APIs are the backbone of today’s web and mobile development, and REST API accounts for around 80 percent. However, a recent analysis from Salt security shows that more than 90 percent of the organizations had an API security incident in the year 2020. Read on to learn how to secure REST API and RESTful API from threat actors.

A REST API is an API that abides by the design principles of representational state transfer architecture style. REST also provides a high level of flexibility and freedom for developers.

If you ignore the nitty gritty’s and security details while designing an API, compromising it will be a cakewalk for any attacker. The Internet is abuzz with several incidents related to leaky APIs.

We did thorough research to find out the critical considerations for the security of the REST API-based applications. Following are key points that you should keep in mind to develop a rock-solid REST API application with a very high level of security.

1. Use TLS (HTTPS, latest version) with GCM ciphers

The security of your API starts here. First and foremost, the credentials used by the API endpoint (passwords, access keys, or JWTs, aka Jason Web Tokens) must be encrypted. By doing this, you will also ensure the security of the data in transit.

The best way to achieve it will be to use TLS, which was earlier known as HTTPS or SSL.

Use the latest version of TLS (1.3 or latest as of date) with GCM ciphers unless you are looking to support legacy clients. Only in that case are you permitted to use some less secure ciphers.

TLS will also inject confidentiality, Integrity, Replay prevention, and authentication. For partner API’s you can also use mutually authenticated client-server certificates.

2. Enforce Access Control for non-public API

If you are working on a non-Public REST API service, ensure to perform access control at each API endpoint.

To minimize latency and reduce coupling, pass on the access control decision-making to the REST endpoints. Also, use an IDP to issue access tokens for centralization of the authentication.

You should centralize user authentication to an identity provider which issues access tokens to secure REST API.

3. Use JSON Web Tokens (JWT) for Access Control

JWTs are JSON data structures that are widely getting adopted as the format of security tokens. These structures contain a set of claims to be used for access control decision-making. You can use cryptographic signatures (preferred) or message authentication code (MAC) for the integrity protection of JWTs.

The challenge with MAC is that if a service can validate a JWT, it can also use the same key to create new JWTs. That means all services using the same ticket have to trust one another.

So if one of the services gets compromised, it will compromise all other services sharing the same key.

4. Use API keys for public REST services

If you do not implement access control, public REST services run for higher risk of facing Pharming and DoS attacks. You can use API keys here to reduce the impact of these attacks. To do this, enforce the API keys for each request. If requests are coming too quickly compared to the threshold value, return a 429 Too Many Requests HTTP response code.

You should revoke the API keys if the client violates the user agreement.

Please be noted that any API keys shared with the clients are at a very high risk of compromise. These keys are often put in Github repositories, which can easily be harvested by using Data Scraping. Please refer to our detailed post around Data Scraping to know more.

Do not rely on API keys to protect any sensitive data or resources.

5. Validate the Endpoint Input

It’s a good practice to validate the length, range, format, and input type. You can enforce implicit input validation by using solid types. For example, numbers, booleans, dates, times, or fixed data ranges in API parameters. Using regular expressions for strings will also be a good idea.

You can also use validation/ sanitation libraries in your specific language.

Enforce an appropriate request size limit and reject requests beyond the limit using 413 Request Entity Too Large HTTP Response.

If you log input validation failures, you will be able to identify attack patterns. If there is someone getting hundreds of failures per second, safe to assume it’s an attack.

6. Restrict the use of HTTP methods

To protect your API endpoint, restrict the HTTP methods which are not required. But, again, that’s something that you can usually do with an API gateway.

Apply a white list of permitted HTTP methods. For example, if you have a read-only endpoint, only give it a read (aka get) access and do not give read-write or post-put access.

Reject all the requests that do not match this whitelisted HTTPS method. For example, you can give a response of 405 Method not Allowed.

7. Validate and send safe response content types

A request or response body for REST should match the intended content type in the header. Otherwise, it can cause misinterpretation and lead to code injection or execution. Therefore, it will be a good idea to document all supported content types in your API.

Use HTTP response status 406 Unacceptable or 415 Unsupported Media type to reject any requests that contain unexpected or missing content-type headers. Also, if you are using an XML parser, please make sure to harden it. Also, you can easily avoid exposing unintended content types by explicitly defining content types.

REST services can typically allow multiple response types, and the client can specify the preferred order of response types using the Accept header in the request.

Don’t just copy the Accept header to the response’s content-type header and reject the request if the header does not specifically contain one of the allowed types.

If the service includes any script code (say Javascript) in their response, they are prone to header injection attacks, and you should be more careful. Also, make sure to send intended content type headers in the response matching the body content.

8. Do not give away information in error messages

Do not reveal details of failure and respond with generic messages. Also, do not pass any technical information or hints to the clients which are for debugging use.

9. Secure any Management endpoints

Do not publish management endpoints across the internet unless explicitly required. If at all it’s required, please change the communication port to a non-standard one and use a multi-factor authentication mechanism. You can further secure it by creating a firewall rule to allow only required traffic.

10. Use security headers correctly to secure REST API

You can return several relevant security-related headers in the HTTP response to instruct the browsers to act in a specific way. You must include the following headers in all API responses:

  • Cache-Control: no-store
  • Content-Security-Policy: frame-ancestors ‘none’
  • Content-Type
  • Strict-Transport-Security
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY

11. Use audit logs carefully and effectively

It will be a good idea to log token validation errors for detecting any attacks. In addition, you should log events before and after any security event. Further, sanitize the log data to protect against log injection attacks to secure REST API.

12. Configure Cross-Origin Resource Sharing properly

CORS (Cross-Origin Resource Sharing) is a protocol that allows you to request restricted resources from another domain which is prohibited by the Same-Origin-Policy (SOP). CORS is considered secure, and it allows for more freedom and functionality.

By providing appropriate CORS Headers, your REST API signals to the browser which domains, AKA origins, are allowed to make JavaScript calls.

13. Do not give sensitive information in HTTP requests

You should be specifically careful not to give away credentials. Passwords, API keys, or security tokens should not appear in the URL. These details can be captured in web server logs.
In POST/PUT requests, you should transfer sensitive data in the request body or request headers, and in GET requests, you should transfer sensitive data in an HTTP Header.

14. Use correct HTTP return codes

HTTP defines several return codes; make sure to use them accurately. E.g., when designing a REST API, don’t use HTTP 200 responses for anything else but success. If there are proper error codes, you can differentiate between errors made by the clients or server.

Hope you found the information helpful around how to secure REST API. Please share any thoughts and feedback in the comments section.