Using CSRF Tokens in APIs

Sanbox will generate and validate CSRF Tokens for web application APIs that use cookies or basic authentication. If you are not familiar with CSRF vulnerabilities, you can check out this article.

Technique

Sanbox generates a randomly generated authentication token in a cookie. The client code reads the cookie, and adds a custom request header with the token in all subsequent requests. The Runtime compares the received cookie value to the request header value, and rejects the request if the values are missing or don't match.

This technique is effective because all browsers implement the same origin policy. Only code from the website on which cookies are set can read the cookies from that site and set custom headers on requests to that site. That means only your application can read this cookie token and set the custom header.

Implementing in Sanbox

API Response Node Implementation

To provide the required cookie to the client, configure the API Response Node with the Create CSRF Token checkbox checked.

API Response Node Security Configuration

When the response for this API is made, Sanbox will send a cookie with the configured cookie name default XSRF-TOKEN . A recommended approach is to create an API Workflow that serves your single-page application with this setting enabled.

API Request Node Implementation

To create an API endpoint that validates the generated token, check the Validate CSRF Token checkbox in the API Request Node configuration. This will cause Sanbox to validate that the cookie named value CSRF Cookie Name and the header named value CSRF Cookie Header match. If the cookie and header do not match, a 401 unauthorized is returned to the client, and the Workflow does not execute.

API Request Node Security Configuration

Sanbox will log failed CSRF Token attempts under a WARN log level in the Runtime. Failed attempts indicate that either your client code has a bug, or someone is actively trying to hack/misuse your application.

Client-Side Code

Client frameworks like Angular support the other half of this technique out-of-the-box. For custom implementation, consider the below client-side JavaScript code:

//Function to read a cookie value
const getCookie = name => {
const escape = s => s.replace(/([.*+?\^${}()|\[\]\/\\])/g, '\\$1');
const match = document.cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
return match ? match[1] : null;
}
//Calling https://localhost/customer an API built with Sanbox
//which requires a CSRF token in the header with POST method
fetch('https://localhost/customer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-XSRF-TOKEN': getCookie('XSRF-TOKEN') //adding the required header here
},
body: JSON.stringify({
name: 'John',
email: 'John@example.com'
}),
});