4

I have an application where I created a REST resource to update a field on the user object to store bookmarked items.

When you do a post request to a rest resource you are required to use a header with X-CSRF-Token.

You can get this by making a call to "/session/token". But I'm wondering if it's OK, if you have a "bookmarks" widget on all pages to include the token in drupal settings.

Or is this some kind of security issue?

Is it better to make a call through javascript to get the token, rather than have it in the drupal settings?

Or as long as you're logged in, having the csrf token in drupal settings is not a problem?

/**
 * Implements hook_preprocess_HOOK().
 */
function mymodule_preprocess_page(&$vars) {

  // Add CSRF token to page for authenticated users.  Token
  // is required by rest resources on POST requests.
  if ($vars['logged_in']) {

    $route = \Drupal::routeMatch()->getRouteObject();
    $is_admin = \Drupal::service('router.admin_context')->isAdminRoute($route);

    if (!$is_admin) {
      $vars['#attached']['drupalSettings']['user']['csrf'] = \Drupal::csrfToken()->get(CsrfRequestHeaderAccessCheck::TOKEN_KEY);
    }
  }
}
3
  • 2
    Probably slightly off-topic from Drupal, but it may be insecure. Best practice would be to store it in something restricted to the origin so that it is not exposed to cross-origin scripts (iframe). Local storage should work for that. Cookies as well.
    – mradcliffe
    Commented Oct 11, 2018 at 19:54
  • 3
    This has some good answers related to JWT tokens and there's some discussion about CSRF as well: stackoverflow.com/questions/44133536/… The accepted answer there is overly cautious about local/session storage because of a fear of browser extensions accessing the token and working around the same origin policy.
    – mradcliffe
    Commented Oct 11, 2018 at 19:57
  • 1
    does it really need to be a REST resource ? if you dont have other clients consuming the resource ... then you can just handle the bookmark action in a controller as Drupal all-ready knows who is accessing it and just return a JsonResponse if it was bookmarked or faild ??
    – taggartJ
    Commented Jan 10, 2019 at 0:19

1 Answer 1

2

Drupal.settings, and other global variables, will be available to cross-origin scripts that happen to be injected (possibly maliciously) into the site. The same applies to any other part of the document body, like meta tags or JSON script tags.

Sensitive tokens should ideally be stored in a place that is restricted to same-origin scripts, which includes cookies and localstorage: https://stackoverflow.com/questions/34782493/difference-between-csrf-and-x-csrf-token

(This shouldn't normally be critical, because script injection shouldn't be possible in the first place, and is a severe vulnerability by itself. But it's probably still a good idea to rely on multiple layers of security.)

1
  • 1
    Thanks! I updated my code a while back to just grab the token when it's needed rather than passing it from the back end. This is better for varnish caching, etc. too.
    – oknate
    Commented Apr 29, 2019 at 18:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.