Django - Forbidden (CSRF cookie not set.)

Thomas picture Thomas · Apr 22, 2012 · Viewed 16.2k times · Source

I have a Django web site with medium traffic (about 4000/5000 visits per day). Today I configured the "LOGGING" option on settings.py to send an email with "Info" level, just check if everything was ok...

There was my surprise, I am getting the following error: [Django] WARNING (EXTERNAL IP): Forbidden (CSRF cookie not set.)

No stack trace available

<WSGIRequest
path:/cadastro/usuario/,
GET:<QueryDict: {}>,
POST:<QueryDict: {**xxxxxxx (some varibles....) and**: u'csrfmiddlewaretoken': [u'4wqRKQXZsTmXJaOkCsGobWyG1rzihc8x'], }>,
COOKIES:{},
META:{'CONTENT_LENGTH': '381',
 'CONTENT_TYPE': 'application/x-www-form-urlencoded',
 'CSRF_COOKIE': 'qzc4i7JdHoQLJ8N5aI9MTlamOZMOKmP0',
 'DOCUMENT_ROOT': '/opt/nginx/html',
 'HTTP_ACCEPT': 'text/html, application/xhtml+xml, */*',
 'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
 'HTTP_ACCEPT_LANGUAGE': 'pt-BR',
 'HTTP_CACHE_CONTROL': 'no-cache',
 'HTTP_CONNECTION': 'Keep-Alive',
 'HTTP_CONTENT_LENGTH': '381',
 'HTTP_CONTENT_TYPE': 'application/x-www-form-urlencoded',
 'HTTP_HOST': 'xxxxxx',
 'HTTP_REFERER': 'http://xxxx/y/z',
 'HTTP_USER_AGENT': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
 'PATH_INFO': u'/y/z',
 'QUERY_STRING': '',
 'REMOTE_ADDR': '187.27.35.123',
 'REMOTE_PORT': '54221',
 'REQUEST_METHOD': 'POST',
 'REQUEST_URI': 'y/z',
 'SCRIPT_NAME': u'',
 'SERVER_NAME': 'xxxxxxx',
 'SERVER_PORT': '80',
 'SERVER_PROTOCOL': 'HTTP/1.1',
 'uwsgi.version': '0.9.6.5',
 'wsgi.errors': <open file 'wsgi_input', mode 'w' at 0xa126338>,
 'wsgi.file_wrapper': <built-in function uwsgi_sendfile>,
 'wsgi.input': <open file 'wsgi_input', mode 'r' at 0xa126a70>,


 'wsgi.multiprocess': True,
 'wsgi.multithread': False,
 'wsgi.run_once': False,
 'wsgi.url_scheme': 'http',
 'wsgi.version': (1, 0)}>

I tried to reproduce this error, but I couldn´t. I test on Firefox and Chrome, cleaned all cookies... Everything is fine. But I am getting this error a dozen of time, always with different IP, so I suppose that it isn't an attack... All my form has {% csrf_token %} and django.middleware.csrf.CsrfViewMiddleware is configured on MIDDLEWARE_CLASSES.

The log message above is very clear that CSRF_COOKIE isnt empty. I am using Django 1.4.

[UPDATED] I Think that theses users dont have cookies enabled... So... The problem is: How to use CSRF with users that don´t have cookies enabled?

Answer

jdi picture jdi · Apr 23, 2012

As I had mentioned in my main comment, you will see that error when a 403 is raised because of a CSRF failure.

You should not need to worry about trying to handle CSRF protection against users without cookies enabled. The very nature of a CSRF attack requires the use of browser cookies. If they are not used, the CSRF-protected request will fail (as you have seen). Thus, you are still protected.

Django lets you set a specific view to use for the client in the event of a CSRF failure: https://docs.djangoproject.com/en/dev/ref/settings/#std%3asetting-CSRF_FAILURE_VIEW

Really, you should not need to do anything other than note that there are requests that are trying to POST to your server in an invalid way.