A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/django/django/commit/2342693b31f740a422abf7267c53b4e7bc487c1b below:

[1.4.x] Made is_safe_url() reject URLs that start with control charac… · django/django@2342693 · GitHub

File tree Expand file treeCollapse file tree 3 files changed

+30

-2

lines changed

Filter options

Expand file treeCollapse file tree 3 files changed

+30

-2

lines changed Original file line number Diff line number Diff line change

@@ -4,6 +4,7 @@

4 4

import sys

5 5

import urllib

6 6

import urlparse

7 +

import unicodedata

7 8

from email.utils import formatdate

8 9 9 10

from django.utils.datastructures import MultiValueDict

@@ -232,9 +233,10 @@ def is_safe_url(url, host=None):

232 233 233 234

Always returns ``False`` on an empty url.

234 235

"""

236 +

if url is not None:

237 +

url = url.strip()

235 238

if not url:

236 239

return False

237 -

url = url.strip()

238 240

# Chrome treats \ completely as /

239 241

url = url.replace('\\', '/')

240 242

# Chrome considers any URL with more than two slashes to be absolute, but

@@ -248,5 +250,10 @@ def is_safe_url(url, host=None):

248 250

# allow this syntax.

249 251

if not url_info[1] and url_info[0]:

250 252

return False

253 +

# Forbid URLs that start with control characters. Some browsers (like

254 +

# Chrome) ignore quite a few control characters at the start of a

255 +

# URL and might consider the URL as scheme relative.

256 +

if unicodedata.category(unicode(url[0]))[0] == 'C':

257 +

return False

251 258

return (not url_info[1] or url_info[1] == host) and \

252 259

(not url_info[0] or url_info[0] in ['http', 'https'])

Original file line number Diff line number Diff line change

@@ -5,3 +5,22 @@ Django 1.4.20 release notes

5 5

*March 18, 2015*

6 6 7 7

Django 1.4.20 fixes one security issue in 1.4.19.

8 + 9 +

Mitigated possible XSS attack via user-supplied redirect URLs

10 +

=============================================================

11 + 12 +

Django relies on user input in some cases (e.g.

13 +

:func:`django.contrib.auth.views.login` and :doc:`i18n </topics/i18n/index>`)

14 +

to redirect the user to an "on success" URL. The security checks for these

15 +

redirects (namely ``django.utils.http.is_safe_url()``) accepted URLs with

16 +

leading control characters and so considered URLs like ``\x08javascript:...``

17 +

safe. This issue doesn't affect Django currently, since we only put this URL

18 +

into the ``Location`` response header and browsers seem to ignore JavaScript

19 +

there. Browsers we tested also treat URLs prefixed with control characters such

20 +

as ``%08//example.com`` as relative paths so redirection to an unsafe target

21 +

isn't a problem either.

22 + 23 +

However, if a developer relies on ``is_safe_url()`` to

24 +

provide safe redirect targets and puts such a URL into a link, they could

25 +

suffer from an XSS attack as some browsers such as Google Chrome ignore control

26 +

characters at the start of a URL in an anchor ``href``.

Original file line number Diff line number Diff line change

@@ -98,7 +98,9 @@ def test_is_safe_url(self):

98 98

'http:\/example.com',

99 99

'http:/\example.com',

100 100

'javascript:alert("XSS")'

101 -

'\njavascript:alert(x)'):

101 +

'\njavascript:alert(x)',

102 +

'\x08//example.com',

103 +

'\n'):

102 104

self.assertFalse(http.is_safe_url(bad_url, host='testserver'), "%s should be blocked" % bad_url)

103 105

for good_url in ('/view/?param=http://example.com',

104 106

'/view/?param=https://example.com',

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4