Search code examples
pythondjangodjango-csrfcsrf-protection

Does django csrf token must be unique on every request?


I have a question about Django CsrfViewMiddleware mechanism. I know, that Django:

  1. Set new csrftoken cookie on every request.
  2. Check, than X-CSRFToken header value (or hidden input "csrfmiddlewaretoken") must be equals to csrftoken cookie.

But Django doesn't check whether token has been used already (example from CsrfViewMiddleware):

if not constant_time_compare(request_csrf_token, csrf_token):
            return self._reject(request, REASON_BAD_TOKEN)

So I can POST multiple requests with the same token (I tested it on my server).

Is it standart behavior, or I have incorrect Django setup? Thanks.


Solution

  • CSRF tokens are not consumed.

    To elaborate on Germano's comment, the reasoning behind it is simple:

    Multiple browser windows / tabs and REST

    Essentially, Django would have to create (and persist, and, in distributed 'cloud' deployment, synchronize) new CSRF tokens for every single page that has been rendered in the past. Essentially, this would easily lead to Denial of Service attacks, where you cannot assume any sensible expiration for the CSRFs.