Search code examples
djangocachingcookiescsrf-protection

Django CSRF protection forces to set "Vary: Cookie" header that leads to inefficient cache


Django's CsrfViewMiddleware sets "Vary: Cookie" header, that means that cache system will take into account not only page URL but also user's Cookies that are unique for each user. So pages don't cache once for all users, but for each user. And in my case I have very loaded site, and such behaviour does not satisfy me.

  • Do I have right view on this issue, or I'm wrong?
  • Can I turn off setting "Vary: Cookie" header without turning off CSRF protection?

Solution

  • Yes, you have the right view on this issue. When you use Django's CSRF-protection for a view, not only are the cookies unique for each user, but also the page content because every CSRF-protected form has a hidden field csrftoken.

    You could work around this issue by setting the value of the csrftoken field to match the cookie on the client side with JavaScript, but this is not provided out of the box by Django.

    However, you will have to ensure that:

    1. your users actually does get a unique CSRF token somehow
    2. as noted by @patrys, CSRF tokens are never accidentally shared between users through the cache (e.g. by stripping Cookie headers from responses)

    There are several opportunities to shoot yourself in the foot and make your site susceptible to CSRF attacks.