diff options
| author | Tim Graham <timograham@gmail.com> | 2015-03-09 20:05:13 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-03-18 08:51:51 -0400 |
| commit | 2a4113dbd532ce952308992633d802dc169a75f1 (patch) | |
| tree | eb181541ed077c28ce423c94a97e7589f16e5632 /django/utils/http.py | |
| parent | e63363f8e075fa8d66326ad6a1cc3391cc95cd97 (diff) | |
[1.7.x] Made is_safe_url() reject URLs that start with control characters.
This is a security fix; disclosure to follow shortly.
Diffstat (limited to 'django/utils/http.py')
| -rw-r--r-- | django/utils/http.py | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/django/utils/http.py b/django/utils/http.py index 6aa5cd38d6..ef88f65cbe 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -5,7 +5,7 @@ import calendar import datetime import re import sys - +import unicodedata from binascii import Error as BinasciiError from email.utils import formatdate @@ -270,9 +270,10 @@ def is_safe_url(url, host=None): Always returns ``False`` on an empty url. """ + if url is not None: + url = url.strip() if not url: return False - url = url.strip() # Chrome treats \ completely as / url = url.replace('\\', '/') # Chrome considers any URL with more than two slashes to be absolute, but @@ -286,5 +287,10 @@ def is_safe_url(url, host=None): # allow this syntax. if not url_info.netloc and url_info.scheme: return False + # Forbid URLs that start with control characters. Some browsers (like + # Chrome) ignore quite a few control characters at the start of a + # URL and might consider the URL as scheme relative. + if unicodedata.category(url[0])[0] == 'C': + return False return ((not url_info.netloc or url_info.netloc == host) and (not url_info.scheme or url_info.scheme in ['http', 'https'])) |
