Cross-Site RequestForgery (CSRF) Protection
The IOTO web server provides comprehensive protection against Cross-Site Request Forgery (CSRF) attacks. CSRF attacks trick a user's browser into sending unauthorized commands to a web server by leveraging an active user session.
To mitigate this, the web server employs CSRF tokens. This document outlines how to configure and use this protection mechanism.
Mitigation Strategy
The CSRF protection is based on a double-submit cookie pattern using a cryptographically strong token.
- A unique CSRF token is generated on the server for a user session.
- The token is sent to the client as a
X-XSRF-TOKENresponse header with the firstGETrequest. The client must save this token. - For subsequent state-changing requests (
POST,PUT,DELETE), the client must include the token in the request, either in theX-XSRF-TOKENheader or as a form parameter. - The server validates the received token against the one stored in the user's session. If they do not match, the request is rejected with a
400 Bad Requeststatus.
This ensures that only requests originating from pages served by your web server can perform sensitive actions.
Configuration
CSRF protection is configured in the web.json5 file. Note that in the configuration and source code, XSRF is used as an abbreviation for CSRF.
To enable CSRF protection for a specific route, add the xsrf: true property to its definition in the routes array.
To ensure client-side scripts can access the CSRF token, the X-XSRF-TOKEN header must be exposed. Add 'Access-Control-Expose-Headers': 'X-XSRF-TOKEN' to the headers section.
{
routes: [
{ match: '/api/resource/', handler: 'action', xsrf: true },
// ... other routes
],
headers: {
'Access-Control-Expose-Headers': 'X-XSRF-TOKEN',
},
}When CSRF protection is enabled for a route, a session is automatically created to store the token on the server. The session ID is returned to the client in a secure, HttpOnly session cookie with SameSite=Lax.
Token Naming
You can customize the token names if required:
- Default header name:
X-XSRF-TOKEN - Default form parameter name:
-xsrf-
Client-Side Workflow
- Enable CSRF protection in the
web.json5configuration for the required routes. - Request a Token: Make an initial
GETrequest to a protected route. - Extract and Store: From the response, extract the value of the
X-XSRF-TOKENheader and store it securely on the client-side. - Submit the Token: For any subsequent
POST,PUT, orDELETErequest, include the stored token in one of two ways:- As an
X-XSRF-TOKENrequest header. - As a hidden form input with the name
-xsrf-.
- As an
If you require CSRF protection and your initial request is either not a GET request or not for a route that has the xsrf configuration set to true, you can call the webAddfor a route that is not a state-changing request, you can call webAddSecurityTokento add the token to the request response to the client. ThewebAddSecurityToken` will create a token if one is not already defined. The 2nd parameter is a boolean to indicate if the token should be recreated.
Implementation Details
- CSRF tokens are only created for routes that have
xsrf: trueenabled. - For
GETrequests to a protected route, thewebAddSecurityToken()function is automatically called to generate and add the CSRF token to the response headers. Otherwise, you can manually callwebAddSecurityTokento add the token to the request response to the client. - For incoming
POST,PUT, orDELETErequests,webCheckSecurityToken()is automatically called to validate the token. Otherwise, you can manually callwebCheckSecurityTokento validate the token. - If the token is missing or invalid, the request is rejected.
