Team we45
June 13, 2018

3 Things to Keep in Mind when writing a Secure REST API

With web applications and microservices being the norm now, Web Application Programming Interface (API) has never been more significant, more specifically the REST API. As more and more companies move towards using multiple micro-services to build their applications, which interact with multiple third party data sources, building a secure API is essential. Even if you build a secure application, an insecure API can be the broken link that makes your security posture inadequate.For those of you who don’t know what a REST API is, here is a quick 101.

What is a REST API?

REST stands for ‘Representational State Transfer’, and is an architectural method for creating an API. It uses HTTP as its underlying communication method, which is the most common method used by web applications to share, add, edit, and delete resources. The verb that is sent with the request informs the API what to do with the resource. For example, a GET request gets data about an entity, POST requests create a new entity. Following are two example of how a REST API shares resources:Example One:

Image shows a HTTP request API call. The highlighted part is the parameters of request.

Image 1: Image shows a HTTP request API call. The highlighted part is the parameters of request

Example Two:

3

Image 2: This image shows a response received following a REST API request. In the previous example, we requested to create a work-space. This image shows the response to that it was created

Now that you know what an REST API is, here are three major aspects of API that you need to keep in mind while creating a secure API.

1. Authentication

Before any kind of resource is shared through an API, the requester needs to have the proper authorization. But, when the first API call is made, the app is not sure its an authenticated resource request. There are two ways to authenticate: Basic Authentication and API Key based authentication.

a) Basic Authentication with SSL/TLS:

The easiest way to authenticate in a REST API is to use HTTP basic authentication transmitted over a SSLv3/TLS. We use a special HTTP header where we add 'username:password' encoded in base64.

               GET / HTTP/1.1

               Host: example.org

               Authorization: Basic Zm9vOmJhcg==

The credentials are encoded not encrypted so by using the HTTP basic authentication we can retrieve the username and password. One of the disadvantages of basic authentication is that we need to send the password over each request. Also, make sure the client - server connection is using the most recent TLS protocol.

b) API Key (Token based authorization):

When there is an API key or a token present in a request, the authorization is provided to access the resource without any prior authentication. An API key is simply a unique token with decent entropy that only the application on both client and server sides know. When creating an API key, the following controls must be taken into account to make sure that the API is secure.

  • Exposure: API keys should be provided on creation and one time only, through file download. It includes instructions on how to ensure that file is readable in the operating system and by only a single entity. Because the API key file is downloaded it makes much harder to acquire API keys.
  • Traceability: You should never expose API Key secrets in the user interface (UI). If a download is required, it must be initiated by the user. Upon initiating, we would know the initiator (user) by having a look at the API keys, which will give us the ability to trace the user.
  • Password Change: The clients that use the API need to be reconfigured to support the password change. If API key is used, the password should be able to change regardless of the API key, which remains the same.

2. Authorization

It is a very common practice to configure the REST API with asterisks (*) to allow access to all requests, because this means session validation is easier. This is a major security flaw, because this by itself isn’t enough to limit activity to legitimate users only. A good practice for this is to whitelist only the necessary HTTP headers such as GET, POST, PUT and DELETE. Restrict from using other HTTP methods, with generic error messages when accessed. And then enable proper session validation. If the session value or the token is not validated upon every state changing request, it makes it vulnerable to privilege escalation, for instance.

Here is an example where we were able to edit session usage, and compromise the host data.

4

Image 3: The image shows that the user order id is “3169”, which is the current session token

5

Image 4: This image shows that the victim user has an order with “3200”

6

Image 5: In this image, the malicious user intercepted a request using an intercepting tool and the request_id parameter is passed into the request

7

Image 6: This image shows that the malicious user intercepted the victim’s request and changed the value of the request_id parameter. Then, forwarded the request to DELETE the order. This attack was only possible because the DELETE HTTP method was improperly configured on the resource

3. Input Validation

In a REST API, it is very critical to validate user inputs on all endpoints like you would do on any parameters. By default, people don’t think about this when creating an API, which makes the application vulnerable. In modern RESTful API web services such as “Jersey”, the validation constraints are automatically enforced at the request in real-time which helps minimize the possibility of  XSS (Cross Site Scripting), SQL Injection, XXE attacks.

a) To protect against XSS attacks, make sure to :

  • Use proper JSON or XML serializer i.e depending on the data-interchange format used.
  • Use .value/.innerText/.textContent rather than .innerHTML updates as this would help protect against simple DOM based XSS attacks.
  • Set security headers such as X-Content-Type-Options: nosniff, X-Frame-Options: deny.

b) To protect against SQL attacks, make sure that you:

  • Use proper JSON or XML serializer i.e depending on the data-interchange format used.
  • Use prepared statements (Parameterized queries).
  • Escape every user supplied inputs which may contain arbitrary queries.
  • Perform whitelist input validation.

c) To protect against XXE (XML external entity attack) attacks, make sure that you:

  • Disable the “Entity Parsing” and “Entity Expansion” to avoid Billion Laughs/XML Bomb via exponential entity expansion attack.
  • Consider having separate CDN (Content Delivery Network) server for handling file uploads which would help in hardening the main server against XXE.

Pretty interesting, right? Click here to know more about DevSecOps.