From 1904022f91d0e987d972359d98993422db11ab3f Mon Sep 17 00:00:00 2001 From: Lukas Klein Date: Wed, 11 Feb 2015 11:09:51 +0100 Subject: [PATCH] [1.8.x] Fixed #24321 -- Improved `utils.http.same_origin` compliance with RFC6454 Backport of 93b3ef9b2e from master. --- django/utils/http.py | 11 +++++++++-- tests/utils_tests/test_http.py | 6 ++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/django/utils/http.py b/django/utils/http.py index d732a9c8253..33515eb410f 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -33,6 +33,11 @@ ASCTIME_DATE = re.compile(r'^\w{3} %s %s %s %s$' % (__M, __D2, __T, __Y)) RFC3986_GENDELIMS = str(":/?#[]@") RFC3986_SUBDELIMS = str("!$&'()*+,;=") +PROTOCOL_TO_PORT = { + 'http': 80, + 'https': 443, +} + def urlquote(url, safe='/'): """ @@ -253,8 +258,10 @@ def same_origin(url1, url2): """ p1, p2 = urlparse(url1), urlparse(url2) try: - return (p1.scheme, p1.hostname, p1.port) == (p2.scheme, p2.hostname, p2.port) - except ValueError: + o1 = (p1.scheme, p1.hostname, p1.port or PROTOCOL_TO_PORT[p1.scheme]) + o2 = (p2.scheme, p2.hostname, p2.port or PROTOCOL_TO_PORT[p2.scheme]) + return o1 == o2 + except (ValueError, KeyError): return False diff --git a/tests/utils_tests/test_http.py b/tests/utils_tests/test_http.py index 19bfa79f1a0..7e48fe70a71 100644 --- a/tests/utils_tests/test_http.py +++ b/tests/utils_tests/test_http.py @@ -18,6 +18,9 @@ class TestUtilsHttp(unittest.TestCase): self.assertTrue(http.same_origin('http://foo.com/', 'http://foo.com')) # With port self.assertTrue(http.same_origin('https://foo.com:8000', 'https://foo.com:8000/')) + # No port given but according to RFC6454 still the same origin + self.assertTrue(http.same_origin('http://foo.com', 'http://foo.com:80/')) + self.assertTrue(http.same_origin('https://foo.com', 'https://foo.com:443/')) def test_same_origin_false(self): # Different scheme @@ -28,6 +31,9 @@ class TestUtilsHttp(unittest.TestCase): self.assertFalse(http.same_origin('http://foo.com', 'http://foo.com.evil.com')) # Different port self.assertFalse(http.same_origin('http://foo.com:8000', 'http://foo.com:8001')) + # No port given + self.assertFalse(http.same_origin('http://foo.com', 'http://foo.com:8000/')) + self.assertFalse(http.same_origin('https://foo.com', 'https://foo.com:8000/')) def test_urlencode(self): # 2-tuples (the norm)