CSRF

NodeBB Development
  • A couple of questions for @Developers

    • instead of submitting a data._csrf with every request that requires it i.e. POST, PUT, UPDATE, DELETE, and having all these scattered all across the app and have every plugin developer worry about it, can we instead do it all in one place using a request header? (csurf supports the header value)
    // maybe in public/src/overrides.js 
    $.ajaxSetup({
        beforeSend: function(xhr, params) {
          var type = params.type.toUpperCase();  
          if ( type !== 'GET' && type !== 'HEAD' && type !== 'OPTIONS') {
                xhr.setRequestHeader('x-csrf-token', app.csrf()); // where app.csrf() finds the token element and returns its value
            }
        }
    });
    
    • Also, when does the csrf token really gets updated for a single user? Say I am browsing the forum and I never really refresh my page, for hours or days, am I risking getting csrf mismatch because it has been updated on the server but not on the client?
      If so, is there a way to update the CSRF on the client, occasionally, via AJAX, kind of what sailsjs supports?
  • CSRF is a tricky issue, because there is a metric ton of misinformation on the internet about how to properly implement it. I'll admit I don't know the finer details about it, so I am open to learning as well.

    1. Why don't we send CSRF in header instead?

      • We could, and it is definitely neater than including it in a plugin/template.
      • What's stopping me? csurf can't generate a csrf token unless the middleware is invoked. When the middleware is invoked, it automatically secures the route (i.e. requires a csrf) for POST/PUT/UPDATE/DELETE, so this cannot be applied globally
      • Could this be sent in with the call that populates app? Possibly, let me look into it.
    2. When does the csrf token get updated?

      • I honestly do not know, and it is abstracted away from us in the csurf module.
      • Some articles on the web suggest it should be trashed and re-generated after every use, some others suggest it should expire after a timeout.
      • Solution: Could code a socket event that would update the stored csrf token on the client side
      • Problem: I don't have access to an event when the csrf token changes for a given session, so I cannot code against it
    3. Way to update the CSRF on the client?

      • I asked about this. I got told this was a really stupid idea because a malicious user could (theoretically, of course) utilise an undisclosed XSS vulnerability to call the same route, retrieve a token, and then make POST calls with the correct CSRF token.

    Edit: Hah, I just realized bobince answered that question on the Security Stack Exchange. school'd.

  • Thanks !

    I don't have access to an event when the csrf token changes for a given session, so I cannot code against it

    Makes sense, I'll look into that.

    bobince answered that question on the Security Stack Exchange

    I commented on the answer; basically What if you don't use JSONP, just limit the route by origin.

  • While I am here, CSRF functionality is cursed, I swear. Every time I modify even a single character in the file, it breaks on @Ted's forum.

  • Re: gh#2424


Suggested Topics