Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the relationship between csrfmiddlewaretoken and csrftoken?

Tags:

django

csrf

I was working with Django to create a website and got some questions about CSRF. I use django.middleware.csrf.CsrfViewMiddleware and add <form action="" method="post">{% csrf_token %} in my POST form.

And when I test the website:

GET / HTTP/1.1
Host: 123.207.137.168:8000

Then, I got cookies

Set-Cookie:csrftoken=Ev8veOH89vFDnG3a0GJUsMXA1oGZXxqXRw2nFWiKrvZ9UE10niTlZCiOxdnoKfTv; expires=Thu, 27-Dec-2018 06:37:41 GMT; Max-Age=31449600; Path=/

But in the html:

<input type='hidden' name='csrfmiddlewaretoken' value='JswHLk4fNpxHkh0OObD1uKiOxSDUzkMDWtqzcsFR5pRdRfYEbNNs1AD23Hkjm2fb' />

So I was wondering why the csrftoken and csrfmiddlewaretoken is different and how did the server use these two value to valid if the request is from the users or hackers?


like image 219
Xuyang Bai Avatar asked Dec 28 '17 06:12

Xuyang Bai


1 Answers

There are some answers in the docs, but looking at the code really solves this "mystery" Basically what django does is the following:

  1. Craft a CSRF secret key
  2. Add a random salt to it and set the salted result as a CSRF cookie (csrftoken)
  3. When user opens a form/request/anything, check if the user has the CSRF cookie set (if they don't have it, craft it as above). If they have it, fetch it, strip the salt and get the real secret, add a random salt and use this as another token (csrfmiddlewaretoken).

Now when you make a POST request for example, the following happens

  1. You send the csrfmiddlewaretoken
  2. Django unsalts the csrf cookie (csrftoken)
  3. Django unsalts the token you sent (csrfmiddlewaretoken)
  4. Django compares them. If the two match, you're ok.

This method with the two tokens is called Double-Submit Cookie. Django's way with the salting allows to keep the same csrf secret for some time without having to renew the key for every request

like image 55
John Paraskevopoulos Avatar answered Sep 21 '22 00:09

John Paraskevopoulos