diff options
| author | Tim Graham <timograham@gmail.com> | 2015-03-09 20:05:13 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2015-03-18 19:20:07 -0400 |
| commit | 011a54315e46acdf288003566b8570440f5ac985 (patch) | |
| tree | 73e17756bfed3b234c5a499eb1fa9cb75a4084e3 /django/utils | |
| parent | 1c83fc88d6928a5ab53bc3dde79dad3cc0bfcfdc (diff) | |
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')
| -rw-r--r-- | django/utils/http.py | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/django/utils/http.py b/django/utils/http.py index 33515eb410..34c17424f6 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -5,6 +5,7 @@ import calendar import datetime import re import sys +import unicodedata from binascii import Error as BinasciiError from email.utils import formatdate @@ -272,9 +273,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 @@ -288,5 +290,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'])) |
