I am currently building a single page application with a JavaScript/HTML front end. The front end makes calls to a WEB API that was written in .NET. Currently I have an HTML page where a user enters their credentials into and clicks login. An AJAX request is then sent to the WEB API which authenticates the user and returns an HTTP-Only cookie that contains a Json Web Token. The browser then sends this cookie on each subsequent request, and the controller validates it.
The above is working well, however it lacks CSRF protection. I am trying to figure out the best way of implementing this. From my research, it looks like there are a few options.
The article at https://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services suggests extracting a token from a cookie and then submitting that as a request header. In order to do this, I would need to drop the HTTP-Only flag, so the JavaScript can access the cookie. I don't think this is the best solution, as it could expose the session information if an XSS vulnerability is found. Is there something I am missing?
Somewhere else I read about sending a separate cookie that contained the CSRF token and pulling the value out of that with JavaScript. Then sending that value as a custom header on subsequent AJAX requests and having the WEB API validate based on that header. I wrote a quick proof of concept application for this and discovered that the browser will still send the cookie the CSRF token was delivered in back on future requests. Does this pose an issue? Could a page with a CSRF attack somehow exploit this?
Similar to the above, but instead of delivering the CSRF token via a cookie, deliver it via a custom header, and have JavaScript read it from there. This seems like it is the most straightforward, but do you see any drawbacks with this approach?
Also, is it safe to keep using a single CSRF token for a user's entire session, or should it be refreshed on every request?