Skip to content

Commit 1a274cc

Browse files
committed
Fixed is_safe_url() to reject URLs that use a scheme other than HTTP/S.
This is a security fix; disclosure to follow shortly.
1 parent a2286ac commit 1a274cc

File tree

2 files changed

+10
-5
lines changed

2 files changed

+10
-5
lines changed

Diff for: django/contrib/auth/tests/views.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ def test_security_check(self, password='password'):
328328
for bad_url in ('http://example.com',
329329
'https://example.com',
330330
'ftp://exampel.com',
331-
'//example.com'):
331+
'//example.com',
332+
'javascript:alert("XSS")'):
332333

333334
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
334335
'url': login_url,
@@ -349,6 +350,7 @@ def test_security_check(self, password='password'):
349350
'/view?param=ftp://exampel.com',
350351
'view/?param=//example.com',
351352
'https:///',
353+
'HTTPS:///',
352354
'//testserver/',
353355
'/url%20with%20spaces/'): # see ticket #12534
354356
safe_url = '%(url)s?%(next)s=%(good_url)s' % {
@@ -522,7 +524,8 @@ def test_security_check(self, password='password'):
522524
for bad_url in ('http://example.com',
523525
'https://example.com',
524526
'ftp://exampel.com',
525-
'//example.com'):
527+
'//example.com',
528+
'javascript:alert("XSS")'):
526529
nasty_url = '%(url)s?%(next)s=%(bad_url)s' % {
527530
'url': logout_url,
528531
'next': REDIRECT_FIELD_NAME,
@@ -541,6 +544,7 @@ def test_security_check(self, password='password'):
541544
'/view?param=ftp://exampel.com',
542545
'view/?param=//example.com',
543546
'https:///',
547+
'HTTPS:///',
544548
'//testserver/',
545549
'/url%20with%20spaces/'): # see ticket #12534
546550
safe_url = '%(url)s?%(next)s=%(good_url)s' % {

Diff for: django/utils/http.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,12 @@ def same_origin(url1, url2):
231231
def is_safe_url(url, host=None):
232232
"""
233233
Return ``True`` if the url is a safe redirection (i.e. it doesn't point to
234-
a different host).
234+
a different host and uses a safe scheme).
235235
236236
Always returns ``False`` on an empty url.
237237
"""
238238
if not url:
239239
return False
240-
netloc = urllib_parse.urlparse(url)[1]
241-
return not netloc or netloc == host
240+
url_info = urllib_parse.urlparse(url)
241+
return (not url_info.netloc or url_info.netloc == host) and \
242+
(not url_info.scheme or url_info.scheme in ['http', 'https'])

0 commit comments

Comments
 (0)