components/python/django/patches/CVE-2016-2512.patch
branchs11u3-sru
changeset 6035 c9748fcc32de
equal deleted inserted replaced
6016:a477397bba8b 6035:c9748fcc32de
       
     1 Patches taken from:
       
     2 https://github.com/django/django/commit/382ab137312961ad62feb8109d70a5a581fe8350
       
     3 https://github.com/django/django/commit/552f03869ea7f3072b3fa19ffb6cb2d957fd8447
       
     4 
       
     5 This is fixed in Django 1.8.11 and 1.9.4
       
     6 
       
     7 --- Django-1.4.22/django/utils/http.py.orig   2016-03-09 19:31:50.474600452 -0800
       
     8 +++ Django-1.4.22/django/utils/http.py     2016-03-09 19:37:10.433043007 -0800
       
     9 @@ -7,8 +7,9 @@ import urlparse
       
    10  import unicodedata
       
    11  from email.utils import formatdate
       
    12 
       
    13 +from django.utils import six
       
    14  from django.utils.datastructures import MultiValueDict
       
    15 -from django.utils.encoding import smart_str, force_unicode
       
    16 +from django.utils.encoding import smart_str, force_unicode, force_text
       
    17  from django.utils.functional import allow_lazy
       
    18 
       
    19  ETAG_MATCH = re.compile(r'(?:W/)?"((?:\\.|[^"])*)"')
       
    20 @@ -237,8 +238,16 @@ def is_safe_url(url, host=None):
       
    21          url = url.strip()
       
    22      if not url:
       
    23          return False
       
    24 -    # Chrome treats \ completely as /
       
    25 -    url = url.replace('\\', '/')
       
    26 +    if six.PY2:
       
    27 +        try:
       
    28 +            url = force_text(url)
       
    29 +        except UnicodeDecodeError:
       
    30 +            return False
       
    31 +    # Chrome treats \ completely as / in paths but it could be part of some
       
    32 +    # basic auth credentials so we need to check both URLs.
       
    33 +    return _is_safe_url(url, host) and _is_safe_url(url.replace('\\', '/'), host)
       
    34 +
       
    35 +def _is_safe_url(url, host):
       
    36      # Chrome considers any URL with more than two slashes to be absolute, but
       
    37      # urlaprse is not so flexible. Treat any url with three slashes as unsafe.
       
    38      if url.startswith('///'):
       
    39 
       
    40 
       
    41 --- Django-1.4.22/tests/regressiontests/utils/http.py.orig   2016-03-09 19:40:41.664196629 -0800
       
    42 +++ Django-1.4.22/tests/regressiontests/utils/http.py     2016-03-09 19:42:38.347335015 -0800
       
    43 @@ -1,3 +1,6 @@
       
    44 +# -*- encoding: utf-8 -*-
       
    45 +from __future__ import unicode_literals
       
    46 +
       
    47  import sys
       
    48 
       
    49  from django.utils import http
       
    50 @@ -100,6 +103,11 @@ class TestUtilsHttp(unittest.TestCase):
       
    51                          'javascript:alert("XSS")'
       
    52                          '\njavascript:alert(x)',
       
    53                          '\x08//example.com',
       
    54 +                        r'http://otherserver\@example.com',
       
    55 +                        r'http:\\testserver\@example.com',
       
    56 +                        r'http://testserver\me:[email protected]',
       
    57 +                        r'http://testserver\@example.com',
       
    58 +                        r'http:\\testserver\confirm\[email protected]',
       
    59                          '\n'):
       
    60              self.assertFalse(http.is_safe_url(bad_url, host='testserver'), "%s should be blocked" % bad_url)
       
    61          for good_url in ('/view/?param=http://example.com',
       
    62 @@ -109,5 +117,14 @@ class TestUtilsHttp(unittest.TestCase):
       
    63                       'https://testserver/',
       
    64                       'HTTPS://testserver/',
       
    65                       '//testserver/',
       
    66 +                     'http://testserver/[email protected]',
       
    67                       '/url%20with%20spaces/'):
       
    68              self.assertTrue(http.is_safe_url(good_url, host='testserver'), "%s should be allowed" % good_url)
       
    69 +        self.assertFalse(http.is_safe_url('Ã view'.encode('latin-1'), host='testserver'))
       
    70 +
       
    71 +        # Valid basic auth credentials are allowed.
       
    72 +        self.assertTrue(http.is_safe_url(r'http://user:pass@testserver/', host='user:pass@testserver'))
       
    73 +        # A path without host is allowed.
       
    74 +        self.assertTrue(http.is_safe_url('/confirm/[email protected]'))
       
    75 +        # Basic auth without host is not allowed.
       
    76 +        self.assertFalse(http.is_safe_url(r'http://testserver\@example.com'))