Functional Attack to API providers

We could have few security attacks to an API:

  • SQL Injections
  • Fuzzing
  • Cross site forgery
  • Session/token hijacking

SQL Injections

In this attack, the attacker tries to identify input parameters used in a SQL statement in order to manipulate the original query

Fuzzing

Fuzz test or Fuzzing is a black box software testing technic which consist to inject random data to a service in order to find bugs

A fuzzer would try combinations of attacks on:

  • numbers (signed/unsigned integers/float…)
  • chars (urls, command-line inputs)
  • metadata : user-input text (id3 tag)
  • pure binary sequences

A common approach to fuzzing is to define lists of “known-to-be-dangerous values” (fuzz vectors) for each type, and to inject them or recombinations.

  • for integers: zero, possibly negative or very big numbers
  • for chars: escaped, interpretable characters / instructions (ex: For SQL Requests, quotes / commands…)
  • for binary: random ones

The hacker, then, analyse the response to understand vulnerability

So pay attention to which type of response error you send back. Don’t send, for instance, sql exception error.

Cross site forgery

In this case the hacker is able to execute a script, which call our API, using the user device.

To avoid this type of attack use POST instead of GET, split transactions in multiple step, add custom headers.

Token and Sessions Hijacking

This is basically a specialisation of the Cross site forgery, with the target of get the token saved on the client device.

So, the user in some way executes the attacker script which will read the token or the session cookie and use it to access to private resources

In this case suggestions are:

expire your token

use complex token pattern

use some additional security header, do not rely only on Access Tokens

REST API Security

Basic Authentication

In this case the user sends credentials in the HTTP Headers “Authorization: Basic <Encoded-Creds>”

The <Encoded-Creds> string is a Base64 string with the format User:Password

Because of the user and password is sent in clear text using http header, it’s not a good idea to send it using http protocol. Use this instead only with ssl/https!

Another issue is that the credentials should be sent on every request

But also, every developer can access to this header.

Moreover in case of mobile app, for instance, they should be hard coded in the app code

Token based authentication

With tokens, it works like this:

  • the client asks for token to the server using credentials
  • the server checks the credentials and replies with a token
  • the client will use always that token to call protected resources
  • the server, every time the client asks for a protected resource check the validity of the token and, if it is valid, replies with the correct response

A token is, basically, an encoded string (hashed or private key for encryption)

It eliminates the need for sessions on API.

The client can send the token in the http header, query parameters, request body.

Tokens can expire and be revocated

API Key and Secret

Similar to user/password but not the same, because they are though for Applications or machines and not for humans.

API key is a API consumer, sometimes known as client key or client id.

API Secret is used by client to prove its identity.

When a client what to access to a resource using API Key and Secret, it will send the Key + a digital signature generated by the Secret.

API Key and Secret could be sent via HTTP Header, query params or request body

OAUTH 2.0

It’s a flexible authorisation framework.

It’s based on different token levels

It describes 5 methods to get the final token to access resources

User has always control of his own data (scope)

Applications/Clients need API Key and Secret.

It’s also known as Social login.

In this authorisation type we have 3 system involved:

  • User Application (the application that own user data)
  • Application Client (API Consumer)
  • Application Server (API provider)

Steps

  1. Application client asks for user authorisation to User Application
  2. User Application responds with a user token (AZ token) for Authorization granted
  3. Application Client with this AZ token asks to Application Server for Authorization to access resources
  4. Application Server looks at this AZ token and if everything is ok responds with an Access Token
  5. Finally the Application client will use the Access Token to access to the resources of the Application Server
API Caching directives

The HTTP cache directive must be executed by all the devices in the chain (firewall, server, client, db,…) that manage the request/response

The directive in included in the HTTP header as:

Cache-Control: "directive-1, directive-2,..."

For instance:

Cache-Control: "private, max-age=60"

Caching Control in the Response

It is useful to manage

  • who can cache the response
  • for how long
  • under what conditions

Caching Control in the Request

It is useful for

  • override caching behavior
  • Protect sensitive data

Caching directive

private vs public

Private means to not cache on the intermediate nodes, but only in the client

Public means cache everywhere

no-store

Used with sensitive data for which they should not be cached at all

no-cache and ETag

With the no-cache directive the server will respond with new fresh data, and the data will not be cached.

The Etag directive represents the hash of the response body, and the client will send it back to the server in order, for the server, to check if the data that have been sent previously to the client are the same of the data that it is going to send again.

In this case the server sends back a 304 (not changed) status code. If the data is changed the server will reply with the 200.

max-age

It’s the time, in seconds, for which the cache will be valid

REST API Error handling

In this article we saw, in general, which HTTP methods and status code to use in CRUD operation.

Now let’s see better which http status code to use in our API.

There are more than 70 status code, but I suggest to use only the common ones.

HTTP Status codeWhen to use
200 OKall GET, PUT, DELETE
201 Createdafter insert (POST)
400 Bad RequestClient wrong params
404 Not Foundduring a GET and the object is not found
401 Not Authorized
403 Forbidden
500 Internal Server Errorin every back end issue

Standard Error Template

{
  text: "message",
  timestamp: new Date(),
  method: httpMethod,
  endpoit: endpointInformation,
  errors: [
    {
      code: codeSpecificApplication, 
      text: "errorMessage",
      hints: ["hints to help the user", "hint 2", ...],
      info: "Link to more info"
}
  ],
  payload: {request payload} (optional, just for debug)
}
Implementing REST API CRUD operations

Basically you should follow these principles:

Use the correct HTTP method

Use the correct HTTP status code

HTTP method

HTTP methodOperation
POSTCreate (or all NOT idempotent operations)
GETRead or Retrieve
PUTUpdate all fields of a resource (basically replace it)
PATCHUpdate only part of a resource
DELETEDelete

HTTP response status

HTTP status codeDescriptionExample
1xxInformational100 Continue
2xxSuccess200 OK
3xxRedirection307 Temporary Redirect
4xxClient Error404 Not Found
5xxServer Error500 Internal Server Error
REST API Endpoint, Resources, Action

Endpoints

To invoke a REST AP you need an endpoint or url.

A url consists of multiple parts.

Best Practice

  • Avoid www domain
  • keep your base URL simple (host+port+application context). Easy to remember
  • If possible use a subdomain (for instance api.yourdomain.com)

Resources

Don’t use verb but just resource name. For instance, don’t use /getItems but simply /items

Specify resource name as plural

Actions

Actions are operation that we ask the system to perform, but they are not CRUD.

/estimates or /buy or /print and so on.

They are mainly POST and PUT, but we may have GET for search actions followed by the parameters for the search

Associations

Associations are resources that contain other resources.

In these cases the rest endpoint could be nested. For example

/items/{id} returns the item details, and /items{id}/reviews or items{id}/photos to return other resources contained in the main item resource

To get a single resource contained in another resource the we will add as last parameter the id of the subresource. For instance items{id}/photos/{idPhoto}

Avoid deep nesting, let’s say 3 levels

Richardson Maturity Model

it is a model (developed by Leonard Richardson) that breaks down the principal elements of a REST approach into three steps: resource, HTTP verbs and hypermedia controls.

Level 0

The base step for a REST API application that uses HTTP as transport layer and nothing else.

Level 1: Resources

In this case instead of calling a generic service we call a more specialised resource service.

For instance, instead of calling “/bookHotel” and passing all information about our booking (hotel, dates, …) we should call ‘/book/hotel/date”

Level 2: HTTP verbs

In the level 2 we use HTTP methods correctly:

GET, to retrieve information (it helps also to manage client caching)

POST and PUT to create/update information, the only real difference is about idempotency:

  • PUT is for idempotency. It means that you could call the PUT service multiple time without creating the object multiple time (so theoretically for update)
  • POST is not used with idempotent service, it means that if you cal a POST service multiple time the object is created multiple times (so theoretically for insert)

When a new object is created (with PUT or POST) the server has to replay with a 201 and a url indicating where to get this new resource using the GET.

Moreover the response code 409 seems a good choice to indicate that someone else has already updated the resource in an incompatible way. It’s better than a 200 with a message string.

Finally the DELETE should be used to remove objects.

Level 3: Hypermedia controls

In the 3rd level, the server not only sends back to the client the data or object state, but also some other link to some action/service the client can call/use for that object.

For instance, if the client call /book/hotel/date, the response could contain also the link to pay that booking, or the link for the room details, and so on. This allows the client to be more independent from the url or from the services of the server.

REST API Contraints

Is your architecture RESTFul?

An architecture could be REST Like or RESTish

To be RESTFull an architecture should follow 6 rules, known as RESTFul Architectures Contraints:

  • Client – Server architectural principle
  • Uniform interface, that is the use of well-defined communication contract between the client and the server
  • Statelessness, the server must not manage the state of the application
  • Caching, the server controls the caching of response using HTTP header for caching
  • Layered system, multiple layer managed independently
  • Code on demand (optional), it means that the server could send to client also some code that could be executed by the client

Based on the rules above, an architecture could have 4 levels/score, from 0 to 3 (Richardson Maturity level)

Client – Server

It’s basically about the separation of the concerns (SoC).

It’s an architectural principle used in programming to separate an application into units, with minimal overlapping between the functions of each individual unit.

So Client and Server are not sharing any code and they are not executed in the same process.

Server doesn’t call directly the Client, and viceversa. They are decoupled. There is no dependency between them.

Client and Server can change without impacting each other.

Uniform Interface

Client and server shares a common technical interface.

An interface is a technical contract for communication between client and server, that’s nothing about business constraint.

the contract is defined by HTTP method and media types.

The advantage is that it decouples totally client and server. They are 100% technologically independent to each other.

the 4 guiding principles

  1. identity of the resource (uri/url), the client can call a url to manipulate the resource
  2. representation of the resource, the data can be represented differently and in a different format from how it is managed on the server side
  3. self-descriptive messages, request and response have enough data to process request and response.
    • Server can use content-type, http status code, host (which host is the response coming from)
    • Client can use Accept.
  4. Hypermedia, it means that the server send back to client not only the data but also the action that the client should execute (known as HATEOAS)

Statelessness

Each client request is indipendent

Server receives all info it needs from the client request

Caching

A typical web application can have multiple level of caching.

Local cache, the one managed by the browser.

Shared cache on the gateway and on the application server

The advantages can be performance ones and scalability

Response messages should be explicitly marked as cacheable or non cacheable .

Caching is managed by the server thanks to the http headers.

cache-control header

cache policy directive: who, how long, under what condition. Ex:

cache-control: private;max-age=120

it means that only the client can ask for caching and that the cache will be stored only foe 120 seconds

expire header

This header specifies a fixed date/time for the expiration of a cached resource. For example, 

Expires: Sat, 13 May 2017 07:00:00 GMT 

means that the cached resource expires on May 13, 2017 at 7:00 am GMT

ETag

 A response header that identifies the version of served content according to a token – a string of characters in quotes, e.g., 

"675af34563dc-tr34" – that changes after a resource is modified. If a token is unchanged before a request is made, the browser continues to use its local version.

Layered System

Client-server architecture consists of multiple layer. It’a a one way path: a layer can’t comunicate with the previous layer.

layers can be moved, added, deleted based on needs

What is an API

API (Application Programming Interface) are like user interfaces but targeted to be consumed by other applications rather than humans.

This interface defines a contract between provider and consumer.

A contract is the exact structure of the request and response

A bit of story: API format

First API format were:

  • XML RPC (Remote Procedure Call)
  • XML SOAP (Simple Object Access Protocol)

Problem

But … XML is heavy in terms of network traffic, so you couldn’t have large payloads crossing over from the webserver to the clients.

XML parsing is CPU and memory intensive

REST Json

Because of previous problems a new exchange format started to be used:

Rest (Representational State Transfer) JSON (Javascript Object Notation)

RESTful

REST stands for REpresentational STate, which means a set of attribute that an object/thing/entity has in a certain moment. This state is managed by a backend system

Rest is not a specific technology, is not a standard

An API is restful when the API has been built using the RESTful architectural style and it follows the principles for RESTful APIs.

HTTP is the preferred protocol to use API with

TYPES OF API

REST API Consumer

  • Private or Internal (part of the same organization)
  • Public or External (outside of the organization)
  • Partner (trusted relationship with the organization)

REST API TYPES

  • Private API, for private consumer
  • Public/External API for public/external consumer
  • Parter API, for partner consumer

There is no particular difference in coding or design these different APIs. What it changes is that they need different aspect in the management of Security, documentation, access request and SLA.

API Security

Private API, consumer are internal and so known (trusted developers). So we can use:

  • Basic auth
  • proprietary schemes

For public and partner API it’s not possible to trust developer, So we can use:

  • key/secret
  • OAuth

Documentation

In case of Partner and private API we are in a “controlled environment”, so no formal documentation

In the public API we talk about uncontrolled environment, we don’t know about unformal documentation, so we need to publish the documentation on a developer portal (which is a good practice also for the other types)

Access Request

for private and partner API, because of controlled environment we can ask it through emails of internal ticketing/process

In case of public API, uncontrolled environment, it’s a good idea to have request for access through a developer portal (which is a good practice also for the other types)

SLA Management

SLA stands for Service Level Agreement, and specifies which service to expect from a service provider and which are the conditions.

Because of API are sort of contracts, consumer and provider has to agree on the quality and condition of the service, for instance up time 99%, throughput 20 calls per seconds and support by email