|
4 | 4 | import time
|
5 | 5 | from pprint import pformat
|
6 | 6 | from urllib import urlencode, quote
|
7 |
| -from urlparse import urljoin |
| 7 | +from urlparse import urljoin, urlparse |
8 | 8 | try:
|
9 | 9 | from cStringIO import StringIO
|
10 | 10 | except ImportError:
|
@@ -117,6 +117,7 @@ def __init__(self, *args, **kwargs):
|
117 | 117 | warnings.warn("CompatCookie is deprecated, use django.http.SimpleCookie instead.",
|
118 | 118 | PendingDeprecationWarning)
|
119 | 119 |
|
| 120 | +from django.core.exceptions import SuspiciousOperation |
120 | 121 | from django.utils.datastructures import MultiValueDict, ImmutableList
|
121 | 122 | from django.utils.encoding import smart_str, iri_to_uri, force_unicode
|
122 | 123 | from django.utils.http import cookie_date
|
@@ -635,19 +636,21 @@ def tell(self):
|
635 | 636 | raise Exception("This %s instance cannot tell its position" % self.__class__)
|
636 | 637 | return sum([len(chunk) for chunk in self._container])
|
637 | 638 |
|
638 |
| -class HttpResponseRedirect(HttpResponse): |
639 |
| - status_code = 302 |
| 639 | +class HttpResponseRedirectBase(HttpResponse): |
| 640 | + allowed_schemes = ['http', 'https', 'ftp'] |
640 | 641 |
|
641 | 642 | def __init__(self, redirect_to):
|
642 |
| - super(HttpResponseRedirect, self).__init__() |
| 643 | + super(HttpResponseRedirectBase, self).__init__() |
| 644 | + parsed = urlparse(redirect_to) |
| 645 | + if parsed.scheme and parsed.scheme not in self.allowed_schemes: |
| 646 | + raise SuspiciousOperation("Unsafe redirect to URL with scheme '%s'" % parsed.scheme) |
643 | 647 | self['Location'] = iri_to_uri(redirect_to)
|
644 | 648 |
|
645 |
| -class HttpResponsePermanentRedirect(HttpResponse): |
646 |
| - status_code = 301 |
| 649 | +class HttpResponseRedirect(HttpResponseRedirectBase): |
| 650 | + status_code = 302 |
647 | 651 |
|
648 |
| - def __init__(self, redirect_to): |
649 |
| - super(HttpResponsePermanentRedirect, self).__init__() |
650 |
| - self['Location'] = iri_to_uri(redirect_to) |
| 652 | +class HttpResponsePermanentRedirect(HttpResponseRedirectBase): |
| 653 | + status_code = 301 |
651 | 654 |
|
652 | 655 | class HttpResponseNotModified(HttpResponse):
|
653 | 656 | status_code = 304
|
|
0 commit comments