Search code examples
csrfcsrf-protection

CSRF Synchronized Token


In the synchronized token pattern I always see the CSRF token in a hidden field or the URL. Is it safe to attach it to the end of an ajax post request and let the server decide if needs to use it? If it is why do people not do it?


Solution

  • The short answer is that it does not matter how you send the token in the synchronizer token pattern as long as it is not automatically sent by the browser if the request is made by another origin (ie. it's not in a cookie). So it's fine to "attach it to the end of an ajax post request" (although I'm not quite sure what you mean by that :) ).

    When talking about a traditional forms applications without ajax calls, a hidden form field is the most convenient way. You just put the token in the hidden field for each form and there's nothing else to do on the client, easy.

    Ajax changes the landscape, ajax calls don't automatically transmit the token, you have to take care of it automatically. For example with jQuery, you would use the beforeSend hook in $.ajaxSetup to automatically add the token to requests. When the request content type is x-www-form-urlencoded, you can just add it as another form variable, when it is a json request with application/json, you could add it as a json value. That would be secure, but I can see two problems.

    One is that the token is kind of "metadata" for the request, not part of your business logic and business data. Also it is a cross-cutting concern across your data structures, not specific to queries. So it's better to keep it out of data structures.

    The other problem is that adding the token to an already contructed request data in beforeSend is tedious. You have to dig into the data structure, find/cretae a variable for the token, etc.

    It is much easier to just send it as a token, and that's what people mostly do when adding the token to ajax requests. Adding a custom request header like X-CSRF-Token or similar is very common, and the server side can then verify the token from there.