Is it possible to set the django csrf cookie to be http-only? Alike to SESSION_COOKIE_HTTPONLY
with session cookie, but for the csrf one?
3 Answers
A new setting, CSRF_COOKIE_HTTPONLY
, is available in Django 1.6+.

- 6,033
- 6
- 38
- 54
-
For anyone with an upgraded instance of Django this should be the answer. Anything else is a hack. – Mike McMahon Dec 22 '14 at 20:40
For Django1.6+, check the accepted answer. For Django1.5 and prev, there is not setting option for this.
You could override the process_response()
method of django.middleware.csrf.CsrfViewMiddleware
and using the customized one instead of CsrfViewMiddleware
in MIDDLEWARE_CLASSES
class Foo(CsrfViewMiddleware):
def process_response(self, request, response):
response = super(Foo, self).process_response(request, response)
response.cookies[settings.CSRF_COOKIE_NAME]['httponly'] = True
return response
Or in another middleware which is invoked after CsrfViewMiddleware
in response
class Foo(object):
def process_response(self, request, response):
if settings.CSRF_COOKIE_NAME in response.cookies:
response.cookies[settings.CSRF_COOKIE_NAME]['httponly'] = True
return response

- 23,575
- 5
- 83
- 90
-
I tried the second method and it works wonderfully, thanks! Just added the middleware before csrf (obvious but it took me a while as I put it after) and put CSRF_COOKIE_NAME in settings and that's all. – Mark Jun 02 '12 at 21:08
-
There is a typo in this code. It should read response = super(Foo, self).process_response(request, response) – adam.lofts Apr 08 '13 at 13:26
-
@Mark I know this is old, but a better option is to use `global_settings.CSRF_COOKIE_NAME` unless you want to manage that setting. – Mike McMahon Dec 22 '14 at 20:41
-
-
No. In the above answer the `CSRF_COOKIE_NAME` Refers to a means to update that specific cookie with a middleware class. Instead of manually specifying one in your settings you can either use the one from global_settings or create an entry in your settings that points to the global_settings version. The 1.6+ answers don't need the above hack and can use `CSRF_COOKIE_HTTPONLY = True` in the settings. Bypassing any workarounds. – Mike McMahon Dec 23 '14 at 03:10
-
@MikeMcMahon As mentioned in [the doc](https://docs.djangoproject.com/en/dev/topics/settings/#using-settings-in-python-code), we should use `django.conf.settings`, no matter whether we have overriden the default value. Did you mean this for the `global_settings`? – okm Dec 23 '14 at 03:22
-
No. For the above work arounds one must define in their own settings file a value for CSRF_COOKIE_NAME. THere are times when we must override a default value but maintain its original value (such as when adding a new template context processor). Django will by default know the value but as soon as we define it in the settings and apply a value we lose what was in the default. When we define it in the settings and set it to `global_settings.SETTING_NAME` we assign the default value without having to know what it is or having to guess and set our own default. – Mike McMahon Dec 23 '14 at 03:39
-
@MikeMcMahon Sorry I didn't get it, but `settings.CSRF_COOKIE_NAME` by default is the value referred by `global_settings.CSRF_COOKIE_NAME`, right? Why do we need to know the original value after having overridden one? – okm Dec 23 '14 at 04:07
-
I don't mean to keep dragging this on :) - `django.conf.settings` contains both the default settings and any overrides. `django.conf.global_settings` is always just the default. My point was that it's easier to have `CSRF_COOKIE_NAME = global_settings.CSRF_COOKIE_NAME` than just `CSRF_COOKIE_NAME = 'csrfcookie'` for the sole purpose of overriding it in the above instance. I see now that it is not required :) and you can just use `CSRF_COOKIE_NAME = settings.CSRF_COOKIE_NAME` or just `settings.CSRF_COOKIE_NAME` directly in the middleware! – Mike McMahon Dec 23 '14 at 19:05
You could actually patch your Django files themselves to mimic the functionality present in later versions, if you have below version 1.6.
The patch is quite simple, and the files modified are visible here:
https://github.com/django/django/commit/720888a14699a80a6cd07d32514b9dcd5b1005fb
Pictures showing the edits are provided in case github goes away.
You don't need to worry about these being overwritten by an upgrade, since the upgrade would include these lines itself.

- 3,424
- 2
- 23
- 33
-
While I consider the odds of imgur going away higher than the odds of github going away, I've done as asked. – Kyle Baker Jan 28 '16 at 21:55