ruby-on-railshttphttp-postcsrfprotect-from-forgery

CSRF token problem on requests from outside the browser to a Rails server


I need to make an HTTP POST request from outside the browser, but the Rails back-end is not accepting the authentication (error 401). I know I need to pass a CSRF token in such cases, but it's not working.

When I make the request through a form on a browser, it works as expected, but when I try to simulate an identical request (in terms of headers and cookies) from outside the browser (using curl, for example), the authentication doesn't work.

Two small changes allowed me success without a browser: (1) turning off protect_from_forgery, which validates the CSRF or (2) using GET instead of POST for the request. In both cases, passing the cookie is enough. That means the problem is definitely related to CSRF stuff.

So, my question is: how can I make a CSRF-protected HTTP POST to a Rails server without using a browser?

To clarify, the process is broken in three steps:

  1. Login: returns a cookie to identify the session;

  2. New: a GET request that returns the CSRF token to be used later (uses the cookie);

  3. Create: a POST request that submits the information I want to create (uses both the session cookie and the CSRF token).

The only step which fails is the third one.


Solution

  • Assuming your CSRF token is cookie-based, then the program you use to make your requests needs to track cookies. Check out the --cookie-jar option in curl.