Code

Opened 3 years ago

Last modified 3 years ago

#16976 new Bug

Bug in Internet Explorer which can lead to exception in Django CSRF framework

Reported by: antmorozov Owned by: nobody
Component: contrib.csrf Version: 1.3
Severity: Normal Keywords: ie, internet explorer, http, https, idn, csrf
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

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:

  1. Internet Explorer (7+, but i have not test it in IE 10 beta).
  2. Django powered site with enabled CSRF protection.
  3. IDN domain on HTTPS (i. e. https://пример.испытание).
  4. JavaScript sends POST request through XMLHTTPRequest (Ajax).

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.

Attachments (3)

settings.py (38 bytes) - added by antmorozov 3 years ago.
Settings file for test case
testcase.py (1.2 KB) - added by antmorozov 3 years ago.
Test case micro project
fixedwsgi.py (874 bytes) - added by antmorozov 3 years ago.
Custom WSGI handler that solves the problem

Download all attachments as: .zip

Change History (6)

Changed 3 years ago by antmorozov

Settings file for test case

Changed 3 years ago by antmorozov

Test case micro project

Changed 3 years ago by antmorozov

Custom WSGI handler that solves the problem

comment:1 follow-up: Changed 3 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

I can't test as I don't have an IDN domain, but accepted on the basis of your description.

comment:2 in reply to: ↑ 1 Changed 3 years ago by antmorozov

Replying to lukeplant:

I can't test as I don't have an IDN domain, but accepted on the basis of your description.

Luke, if you give me your IP I can set it as A record on subdomain of my IDN.

comment:3 Changed 3 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

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as new
The owner will be changed from nobody to anonymous. Next status will be 'assigned'
as The resolution will be set. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.