From 03d0c05fdfd3de5f36bf54470ed03018295497c7 Mon Sep 17 00:00:00 2001 From: UmanShahzad Date: Sat, 29 Apr 2017 19:10:43 -0400 Subject: [PATCH] [1.11.x] Fixed #28142 -- Fixed is_safe_url() crash on invalid IPv6 URLs. Backport of 856072dd4a3e479aa09b0ab6b498ff599ca2a809 from master --- django/utils/http.py | 5 ++++- docs/releases/1.11.2.txt | 3 +++ tests/utils_tests/test_http.py | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/django/utils/http.py b/django/utils/http.py index f47a09a2dc..1fbc11b6fb 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -387,7 +387,10 @@ def _is_safe_url(url, allowed_hosts, require_https=False): # urlparse is not so flexible. Treat any url with three slashes as unsafe. if url.startswith('///'): return False - url_info = _urlparse(url) + try: + url_info = _urlparse(url) + except ValueError: # e.g. invalid IPv6 addresses + return False # Forbid URLs like http:///example.com - with a scheme, but without a hostname. # In that URL, example.com is not the hostname but, a path component. However, # Chrome will still consider example.com to be the hostname, so we must not diff --git a/docs/releases/1.11.2.txt b/docs/releases/1.11.2.txt index f4d1398094..fd6b7083e9 100644 --- a/docs/releases/1.11.2.txt +++ b/docs/releases/1.11.2.txt @@ -15,3 +15,6 @@ Bugfixes * Changed ``contrib.gis`` to raise ``ImproperlyConfigured`` rather than ``GDALException`` if ``gdal`` isn't installed, to allow third-party apps to catch that exception (:ticket:`28178`). + +* Fixed ``django.utils.http.is_safe_url()`` crash on invalid IPv6 URLs + (:ticket:`28142`). diff --git a/tests/utils_tests/test_http.py b/tests/utils_tests/test_http.py index f6f711c72f..b435e33e44 100644 --- a/tests/utils_tests/test_http.py +++ b/tests/utils_tests/test_http.py @@ -109,6 +109,8 @@ class TestUtilsHttp(unittest.TestCase): 'http:999999999', 'ftp:9999999999', '\n', + 'http://[2001:cdba:0000:0000:0000:0000:3257:9652/', + 'http://2001:cdba:0000:0000:0000:0000:3257:9652]/', ) for bad_url in bad_urls: with ignore_warnings(category=RemovedInDjango21Warning):