Referer header security check for access to REST APIs

When calling Rest APIs in IBM CÃºram Social Program Management in order to combat Cross-Site Request Forgery (CSRF) attacks that can occur in web applications, a security check is performed on the value sent in the request Referer header, for every REST API request sent to the server. This validates where the API request has come from. If this check fails, the REST API will return the following response:

{

“errors” : [ {

“code” : -150210,

“message” : “The request is forbidden as the specified Referer header

is not allowed.”,

“level” : “error”

} ]

}

If a REST API is being called from a web application, the value of the Referer header that is sent as part of the API request will contain the URL of where the request originates from (this will include the domain of where the web application is running), and the domain part of the URL must match a domain or sub domain that is specified in the curam.rest.refererDomains property. CSRF only applies to web applications. The value for the Referer header is automatically set by the browser and cannot be modified.

CSRF does not apply if a REST API is being called from anything other than a web application, however if the Referer header is not set and therefore does not contain a value, then the security check will still fail. So for any non-web applications that do not automatically set a value for the Referer header (for example system-to-system calls, mobile apps, Rest clients for testing etc) an appropriate value will need to be set by the caller of the API. This value can be a URI scheme name that exactly matches ‘curam’, for example curam://foundational.app.

Details on how to correctly set the â€˜curam.rest.refererDomainsâ€™ property, or to set a Referer header if required, in order to pass the security check will depend on whether the Rest APIs are being accessed from a web application or not.

Setting the Referer header for direct access to Rest APIs for viewing or testing purposes:

The CÃºram server must be running, and a valid user who has access to the APIâ€™s underlying rest facade must be logged in.

If direct access to a Rest API is required, this cannot be done by entering the URL endpoint of the API directly in the browser. This is because no value will be sent in the Referer header, and therefore the security check will fail. There are a number of ways that the Referer header may be set and included with the Rest API request.

1. Use a REST client

Most browsers have extensions for REST clients, which are simple to install and use, for example RESTer for Firefox.

Figure 1: How to set the Referer header while making an API request using the RESTer extension for Firefox.

The value used for the Referer header can be a URI scheme name that exactly matches ‘curam’, for example curam://my-app.

One point to note is that not all REST clients will permit the Referer header to be set, or may even strip out the value after being set, as this is a security header. So this is something to watch out for when choosing a REST client.

2. Use a cURL command

If the cURL command line tool is installed, the Referer header may be sent in a cURL command, for example:

3. Use a Swagger UI tool

A Swagger UI tool is an excellent tool to both view the details of an API, and to send a request to the API. Instructions for setting up the Swagger UI tool to run in Tomcat can be found â€˜hereâ€™. The Swagger UI tool will display all the APIs publicly available in CÃºram Social Program Management, and the details of each API can be seen by clicking on the API endpoint.

Figure 2: Viewing details of an API using a Swagger UI tool.

Since a Swagger UI tool is a web application, if using the â€˜Try It Outâ€™ button to make an API request to the Curam server, the browser will automatically set the Referer header, and will include the domain of where the Swagger UI tool is running.

In this case, the â€˜curam.rest.refererDomainsâ€™ property needs to be set, to include the domain or IP address of where the Swagger UI tool is running. If you are unsure of what domain this is, you can use the network tools of your browser to see what value for the Referer header is sent in the request. Setting this property is covered in more detail in the last section of this article.

Figure 3: Sending an API request from a Swagger UI tool using the ‘Try It out!’ button, with the browser’s Network tool displayed in the bottom half of the browser screen.

In the above screenshot, the Referer header being sent is â€˜http://localhost:9080/swaggerâ€™ (which can be seen by opening the browser’s Network tool), so the â€˜curam.rest.refererDomainsâ€™ property must contain â€˜localhostâ€™ as one of its comma separated values.

Setting the Referer header when access to the Rest API is from another system or a mobile app

Usually, the caller of the API (e.g. a mobile app) must set the Referer header on each API request. The value used can be a URI scheme name that exactly matches ‘curam’, for example curam://my-app.

The only time where this may not be the case, is if the system that calls the Rest API automatically sets the value for the Referer header. An example of where this may happen could be when a web application redirects to a login server, and once authenticated the login server redirects to the API. In this case, the login server may have set the Referer header to contain its own domain name, and so the â€˜curam.rest.refererDomainsâ€™ property will need to be set to include this domain. Setting this property is is covered in more detail in the next section.

Setting the â€˜curam.rest.refererDomainsâ€™ property, when access to the Rest API is from a web application

If access to the Rest API is from a web application, the browser will automatically set a value for the Referer header, which will include the domain name or IP address of where the web application is running. This value must match one of the comma separated values that has been set in the â€˜curam.rest.refererDomainsâ€™ property.

For example, in a development environment if a web application is running on localhost, then the browser will set the Referer header to be â€˜http://localhost:<port>/<web-app-page>, and the â€˜curam.rest.refererDomainsâ€™ must contain â€˜localhostâ€™.

Or in a production environment, if a web application is running on a domain called â€˜my-domainâ€™, and the browser sets the Referer header value to â€˜https://my-domain.com/<web-app-page>, then the â€˜curam.rest.refererDomainsâ€™ must contain â€˜my-domain.comâ€™.

The â€˜curam.rest.refererDomainsâ€™ property may be set in the same way as any other property in Curam â€“ either via the Curam application while logged in as a System Administrator, or directly on the Properties database table in a development environment. For either method, the server will need to be restarted for the change to be visible by the Rest Infrastructure.

The value for the property can contain a comma separated list of allowed domains, sub domains, or IP addresses. For example if the property is set to a value of â€˜ibm.com,my-domain.com,9.101.123.123â€™, then access from web applications running at â€˜https://example1.ibm.com:9044â€™, â€˜http://example2.ibm.comâ€™, â€˜https://my-domain.comâ€™ and â€˜http:// 9.101.123.123â€™ would all pass the Referer header security check.