Bug in Internet Explorer which can lead to exception in Django CSRF framework
|Reported by:||antmorozov||Owned by:||nobody|
|Severity:||Normal||Keywords:||ie, internet explorer, http, https, idn, csrf|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
I have found a bug in Inernet Explorer which can lead to exception in Django in some cases.
This exception can be reproduced in these conditions:
- Internet Explorer (7+, but i have not test it in IE 10 beta).
- Django powered site with enabled CSRF protection.
- IDN domain on HTTPS (i. e. https://пример.испытание).
In this case IE sends to server wrong Referer header, in unicode istead of punycode format (https://пример.испытание istead of https://xn--e1afmkfd.xn--80akhbyknj4f like other browsers). At the same time the Host header is right (in punycode).
This leads to the following exception:
Traceback (most recent call last): File "/path/to/django/core/handlers/base.py", line 105, in get_response response = middleware_method(request, callback, callback_args, callback_kwargs) File "/path/to/middleware/csrf.py", line 169, in process_view logger.warning('Forbidden (%s): %s' % (reason, request.path), UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 45: ordinal not in range(128)
But even without exception the request will not pass the referer test, as HTTP_REFERER and HTTP_HOST variables will be different.
I have prepared the micro django project with which you can reproduce the problem: settings.py and testcase.py in attachment (remember about IDN domain and HTTPS).
To solve the problem we need to check and correct HTTP_REFERER value at the stage of getting enviroment variables, in HTTP handler. In my projects I use custom WSGI handler (fixwsgi.py in attachment). On its basis it is possible to write a patch for django.core.handlers.wsgi.WSGIRequest and django.core.handlers.modpython.ModPythonRequest.
Sorry for my bad english. I wish common sense is understandable.
Change History (7)
comment:1 follow-up: ↓ 2 Changed 4 years ago by lukeplant
- Component changed from HTTP handling to contrib.csrf
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
- Triage Stage changed from Unreviewed to Accepted
comment:3 Changed 4 years ago by antmorozov
- Summary changed from Bug in Inernet Explorer which can lead to exception in Django CSRF framework to Bug in Internet Explorer which can lead to exception in Django CSRF framework