Loading django/http/__init__.py +12 −9 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import re import time from pprint import pformat from urllib import urlencode, quote from urlparse import urljoin from urlparse import urljoin, urlparse try: from cStringIO import StringIO except ImportError: Loading Loading @@ -117,6 +117,7 @@ class CompatCookie(SimpleCookie): warnings.warn("CompatCookie is deprecated, use django.http.SimpleCookie instead.", PendingDeprecationWarning) from django.core.exceptions import SuspiciousOperation from django.utils.datastructures import MultiValueDict, ImmutableList from django.utils.encoding import smart_str, iri_to_uri, force_unicode from django.utils.http import cookie_date Loading Loading @@ -635,19 +636,21 @@ class HttpResponse(object): raise Exception("This %s instance cannot tell its position" % self.__class__) return sum([len(chunk) for chunk in self._container]) class HttpResponseRedirect(HttpResponse): status_code = 302 class HttpResponseRedirectBase(HttpResponse): allowed_schemes = ['http', 'https', 'ftp'] def __init__(self, redirect_to): super(HttpResponseRedirect, self).__init__() super(HttpResponseRedirectBase, self).__init__() parsed = urlparse(redirect_to) if parsed.scheme and parsed.scheme not in self.allowed_schemes: raise SuspiciousOperation("Unsafe redirect to URL with scheme '%s'" % parsed.scheme) self['Location'] = iri_to_uri(redirect_to) class HttpResponsePermanentRedirect(HttpResponse): status_code = 301 class HttpResponseRedirect(HttpResponseRedirectBase): status_code = 302 def __init__(self, redirect_to): super(HttpResponsePermanentRedirect, self).__init__() self['Location'] = iri_to_uri(redirect_to) class HttpResponsePermanentRedirect(HttpResponseRedirectBase): status_code = 301 class HttpResponseNotModified(HttpResponse): status_code = 304 Loading tests/regressiontests/httpwrappers/tests.py +17 −2 Original line number Diff line number Diff line import copy import pickle from django.http import (QueryDict, HttpResponse, SimpleCookie, BadHeaderError, from django.core.exceptions import SuspiciousOperation from django.http import (QueryDict, HttpResponse, HttpResponseRedirect, HttpResponsePermanentRedirect, SimpleCookie, BadHeaderError, parse_cookie) from django.utils import unittest Loading Loading @@ -243,6 +246,18 @@ class HttpResponseTests(unittest.TestCase): self.assertRaises(BadHeaderError, r.__setitem__, 'test\rstr', 'test') self.assertRaises(BadHeaderError, r.__setitem__, 'test\nstr', 'test') def test_unsafe_redirects(self): bad_urls = [ 'data:text/html,<script>window.alert("xss")</script>', 'mailto:test@example.com', 'file:///etc/passwd', ] for url in bad_urls: self.assertRaises(SuspiciousOperation, HttpResponseRedirect, url) self.assertRaises(SuspiciousOperation, HttpResponsePermanentRedirect, url) class CookieTests(unittest.TestCase): def test_encode(self): """ Loading Loading
django/http/__init__.py +12 −9 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import re import time from pprint import pformat from urllib import urlencode, quote from urlparse import urljoin from urlparse import urljoin, urlparse try: from cStringIO import StringIO except ImportError: Loading Loading @@ -117,6 +117,7 @@ class CompatCookie(SimpleCookie): warnings.warn("CompatCookie is deprecated, use django.http.SimpleCookie instead.", PendingDeprecationWarning) from django.core.exceptions import SuspiciousOperation from django.utils.datastructures import MultiValueDict, ImmutableList from django.utils.encoding import smart_str, iri_to_uri, force_unicode from django.utils.http import cookie_date Loading Loading @@ -635,19 +636,21 @@ class HttpResponse(object): raise Exception("This %s instance cannot tell its position" % self.__class__) return sum([len(chunk) for chunk in self._container]) class HttpResponseRedirect(HttpResponse): status_code = 302 class HttpResponseRedirectBase(HttpResponse): allowed_schemes = ['http', 'https', 'ftp'] def __init__(self, redirect_to): super(HttpResponseRedirect, self).__init__() super(HttpResponseRedirectBase, self).__init__() parsed = urlparse(redirect_to) if parsed.scheme and parsed.scheme not in self.allowed_schemes: raise SuspiciousOperation("Unsafe redirect to URL with scheme '%s'" % parsed.scheme) self['Location'] = iri_to_uri(redirect_to) class HttpResponsePermanentRedirect(HttpResponse): status_code = 301 class HttpResponseRedirect(HttpResponseRedirectBase): status_code = 302 def __init__(self, redirect_to): super(HttpResponsePermanentRedirect, self).__init__() self['Location'] = iri_to_uri(redirect_to) class HttpResponsePermanentRedirect(HttpResponseRedirectBase): status_code = 301 class HttpResponseNotModified(HttpResponse): status_code = 304 Loading
tests/regressiontests/httpwrappers/tests.py +17 −2 Original line number Diff line number Diff line import copy import pickle from django.http import (QueryDict, HttpResponse, SimpleCookie, BadHeaderError, from django.core.exceptions import SuspiciousOperation from django.http import (QueryDict, HttpResponse, HttpResponseRedirect, HttpResponsePermanentRedirect, SimpleCookie, BadHeaderError, parse_cookie) from django.utils import unittest Loading Loading @@ -243,6 +246,18 @@ class HttpResponseTests(unittest.TestCase): self.assertRaises(BadHeaderError, r.__setitem__, 'test\rstr', 'test') self.assertRaises(BadHeaderError, r.__setitem__, 'test\nstr', 'test') def test_unsafe_redirects(self): bad_urls = [ 'data:text/html,<script>window.alert("xss")</script>', 'mailto:test@example.com', 'file:///etc/passwd', ] for url in bad_urls: self.assertRaises(SuspiciousOperation, HttpResponseRedirect, url) self.assertRaises(SuspiciousOperation, HttpResponsePermanentRedirect, url) class CookieTests(unittest.TestCase): def test_encode(self): """ Loading