Monday, August 9, 2021

CSRF protection with Sails JS

Cross-site request forgery (CSRF) is a type of attack which forces an end user to execute unwanted actions on a web application backend with which he/she is currently authenticated. In other words, without protection, cookies stored in a browser like Google Chrome can be used to send requests to Chase.com from a user's computer whether that user is currently visiting Chase.com or Horrible-Hacker-Site.com.Using tokens protects your Sails app against cross-site request forgery (or CSRF) attacks. A would-be attacker needs not only a user's session cookie, but also this timestamped, secret CSRF token, which is refreshed/granted when the user visits a URL on your app's domain. This allows you to have certainty that your users' requests haven't been hijacked, and that the requests they're making are intentional and legitimate.

CSRF tokens are like limited-edition swag. While a session tells the server that a user "is who they say they are", a csrf token tells the server they "were where they say they were". When CSRF protection is enabled in your Sails app, all non-GET requests to the server must be accompanied by a special "CSRF token", which can be included as either the '_csrf' parameter or the 'X-CSRF-Token' header.

Enabling CSRF protection requires managing the token in your front-end app. In traditional form submissions, this can be easily accomplished by sending along the CSRF token as a hidden input in your <form>. Or better yet, include the CSRF token as a request param or header when you send AJAX requests. To do that, you can either fetch the token by sending a request to the route where you mounted security/grant-csrf-token, or better yet, harvest the token from view locals using the exposeLocalsToBrowser partial.

(a) For modern, view-driven hybrid apps that submit forms with AJAX:

Use the exposeLocalsToBrowser partial to provide access to the token from your client-side JavaScript, e.g.:

<%- exposeLocalsToBrowser() %>

<script>

  $.post({

    foo: 'bar',

    _csrf: window.SAILS_LOCALS._csrf

  })

</script>

(b) For single-page apps with static HTML:

Fetch the token by sending a GET request to the route where you mounted the security/grant-csrf-token. It will respond with JSON, e.g.:

{ _csrf: 'ajg4JD(JGdajhLJALHDa' }

For traditional HTML form submissions:

<form>

  <input type="hidden" name="_csrf" value="<%= _csrf %>" />

</form>


Enabling CSRF protection

#

Sails bundles optional CSRF protection out of the box. To enable the built-in enforcement, just make the following adjustment to sails.config.security.csrf (conventionally located in your project's config/security.js file):


csrf: true


You can also turn CSRF protection on or off on a per-route basis by adding csrf: true or csrf: false to any route in your config/routes.js file.


Note that if you have existing code that communicates with your Sails backend via POST, PUT, or DELETE requests, you'll need to acquire a CSRF token and include it as a parameter or header in those requests. More on that in a sec.


CSRF tokens

#

Like most Node applications, Sails and Express are compatibile with Connect's CSRF protection middleware for guarding against such attacks. This middleware implements the Synchronizer Token Pattern. When CSRF protection is enabled, all non-GET requests to the Sails server must be accompanied by a special token, identified by either a header or a parameter in the query string or HTTP body.


CSRF tokens are temporary and session-specific; e.g. Imagine Mary and Muhammad are both shoppers accessing our e-commerce site running on Sails, and CSRF protection is enabled. Let's say that on Monday, Mary and Muhammad both make purchases. In order to do so, our site needed to dispense at least two different CSRF tokens- one for Mary and one for Muhammad. From then on, if our web backend received a request with a missing or incorrect token, that request will be rejected. So now we can rest assured that when Mary navigates away to play online poker, the 3rd party website cannot trick the browser into sending malicious requests to our site using her cookies.


References

https://sailsjs.com/documentation/concepts/security/csrf

No comments:

Post a Comment