by fpereiro on 2/7/20, 5:10 PM with 0 comments
To prevent CSRF, I was sending said session cookie as an extra field with every POST request (double submit cookie pattern: https://medium.com/cross-site-request-forgery-csrf/double-submit-cookie-pattern-65bb71d80d9f). Now that the session is not readable from javascript, I need to create a separate CSRF token.
Based on great feedback from the community (see https://news.ycombinator.com/item?id=22209588 and https://github.com/fpereiro/backendlore/issues/12), I'm considering the following approach:
- On every successful login, create a new secret/token (using the same crypto mechanism I use to create the session secret, but a different secret altogether) and store it on the database, tied to the session itself. Set both the session and the CSRF token to expire at the same time. - Every time I get a request with a valid session, renew the life of both the session AND the associated CSRF token. - On every successful login, return the CSRF token in the body so that it can be read by client-side javascript. - Set up an endpoint to retrieve the associated CSRF token for its session. If no session is present (or the session has expired), return a 403 code. This also solves the problem of letting the client-side app know whether the user is logged in or not (I would hit this GET /csrf endpoint when the javascript loads to determine whether there's a valid session available).
My understanding is that, as long as the browser supports Same-Origin Policy (https://en.wikipedia.org/wiki/Same-origin_policy), a CSRF attacker could not submit a GET request to my server and obtain the result. If you see any security issues in the above scheme - or if you use a similar scheme and know it to be secure - please let me know. Thank you very much for your feedback!