10
votes

Being a beginner at cookies, CSRF and Django (using 1.4), from what I can make out this is how it works, please correct me where I go wrong...

The following applies where django.middleware.csrf.CsrfViewMiddleware is included in the MIDDLEWARE_CLASSES tuple.

Where a POST form includes the csrf_token tag, and the view concerned passes RequestContext to the template, requesting the page means Django includes a hidden form field which contains an alphanumeric string. Django also returns to the browser a cookie with the name set to csrftoken and value set to the same alphanumeric string.

When receiving the form submission, Django checks that the alphanumeric string value from the hidden form field matches and the csrftoken cookie received from the browser. If they don't match a 403 response is issued.

A CSRF attack might come in the form of a malicious web site that includes an iframe. The iframe includes a POST form and some JavaScript. The form's action attribute points to my Django site. The form is designed to do something nasty at my site, and the JS submits the form when the iframe is loaded.

The browser would include the csrftoken cookie in the header of the form submission. However, the form would not include the hidden field with the matching alphanumeric string, so a 403 is returned and the attack fails. If the iframe JS tried to access the cookie, so as to create the correct hiddden form field, the browser would prevent it from doing so.

Is this correct?

2
I don't see anything wrong. Maybe others will, but in general, you got it.Zashas

2 Answers

1
votes

I would say that you are right. You will find here my own formulation of it.

To summarize:

  • The CSRF token is sent from the code, which means that the malicious code must know it.
  • The CSRF token is stored in a cookie and sent by the browser.
  • The attacker cannot access the cookie because of the same-origin policy.
  • The server can simply verify that the "safe" value coming from the cookie is the same as the one coming from the code.
1
votes

I think what you want is described here in the official Django Documentation. https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#how-it-works

Above link was broken when I tried, but for version 1.7 this works: https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/