0
votes

Reading this section of the Django docs they recommend setting a csrftoken in a cookie and then having the client-side framework put this in a header which will be validated on a server-side request. However, doesn't having the token in a cookie defeat the purpose because the cookies are sent on every user's request?

Or is the "security" here that Django checks for that value in a header rather than checking the cookie value itself?

I do understand why this works for synchronous submissions, but in that case the csrftoken is written directly to the page rather than stored in a cookie, which seems more secure.

From the OWASP page on reviewing code for CSRF:

Checking if the request has a valid session cookie is not enough, we need check if a unique identifier is sent with every HTTP request sent to the application. CSRF requests WON'T have this valid unique identifier. The reason CSRF requests won't have this unique request identifier is the unique ID is rendered as a hidden field on the page and is appended to the HTTP request once a link/button press is selected. The attacker will have no knowledge of this unique ID, as it is random and rendered dynamically per link, per page.

2

2 Answers

3
votes

You've misunderstood a few things.

The token is always in a cookie; the code you link to is for getting it out of the cookie in your JS so that you can send it back.

And the point is, as your quote shows, that an attacker trying to post from a page that is not on the site will not have that cookie, so won't be able to inject the right value into the form or the header.

0
votes

I'm not familiar with django csrf protection, but I think it's work like other csrf protections in other frameworks.

The trick is, send csrf token to the client through cookie and client use header to send it back to the server. Server ignore cookie, but not header. How it prevents csrf attack? For example, attacker can bind <img src="yourwebsite.com/action/destroy/data"> (or sends post request through javascript). Your browser sends csrf cookie (and also session cookie) with it. Because header is missing - attack is prevented.

Same with forms. I think both, headers and forms are equal secure.

But in both cases you are lost, if you have a xss vulnerability.

EDIT: as Daniel points out, it's make sense to remove csrf cookie. But this is not for security reason.