Refs #23919 -- Assumed request COOKIES and META are str
This commit is contained in:
parent
89501d9298
commit
c688336ebc
|
@ -11,7 +11,6 @@ from django.utils.cache import (
|
||||||
cc_delim_re, get_conditional_response, set_response_etag,
|
cc_delim_re, get_conditional_response, set_response_etag,
|
||||||
)
|
)
|
||||||
from django.utils.deprecation import MiddlewareMixin, RemovedInDjango21Warning
|
from django.utils.deprecation import MiddlewareMixin, RemovedInDjango21Warning
|
||||||
from django.utils.encoding import force_text
|
|
||||||
|
|
||||||
|
|
||||||
class CommonMiddleware(MiddlewareMixin):
|
class CommonMiddleware(MiddlewareMixin):
|
||||||
|
@ -157,10 +156,10 @@ class BrokenLinkEmailsMiddleware(MiddlewareMixin):
|
||||||
if response.status_code == 404 and not settings.DEBUG:
|
if response.status_code == 404 and not settings.DEBUG:
|
||||||
domain = request.get_host()
|
domain = request.get_host()
|
||||||
path = request.get_full_path()
|
path = request.get_full_path()
|
||||||
referer = force_text(request.META.get('HTTP_REFERER', ''), errors='replace')
|
referer = request.META.get('HTTP_REFERER', '')
|
||||||
|
|
||||||
if not self.is_ignorable_request(request, path, domain, referer):
|
if not self.is_ignorable_request(request, path, domain, referer):
|
||||||
ua = force_text(request.META.get('HTTP_USER_AGENT', '<none>'), errors='replace')
|
ua = request.META.get('HTTP_USER_AGENT', '<none>')
|
||||||
ip = request.META.get('REMOTE_ADDR', '<none>')
|
ip = request.META.get('REMOTE_ADDR', '<none>')
|
||||||
mail_managers(
|
mail_managers(
|
||||||
"Broken %slink on %s" % (
|
"Broken %slink on %s" % (
|
||||||
|
|
|
@ -15,7 +15,6 @@ from django.urls import get_callable
|
||||||
from django.utils.cache import patch_vary_headers
|
from django.utils.cache import patch_vary_headers
|
||||||
from django.utils.crypto import constant_time_compare, get_random_string
|
from django.utils.crypto import constant_time_compare, get_random_string
|
||||||
from django.utils.deprecation import MiddlewareMixin
|
from django.utils.deprecation import MiddlewareMixin
|
||||||
from django.utils.encoding import force_text
|
|
||||||
from django.utils.http import is_same_domain
|
from django.utils.http import is_same_domain
|
||||||
|
|
||||||
logger = logging.getLogger('django.security.csrf')
|
logger = logging.getLogger('django.security.csrf')
|
||||||
|
@ -107,7 +106,7 @@ def rotate_token(request):
|
||||||
|
|
||||||
def _sanitize_token(token):
|
def _sanitize_token(token):
|
||||||
# Allow only ASCII alphanumerics
|
# Allow only ASCII alphanumerics
|
||||||
if re.search('[^a-zA-Z0-9]', force_text(token)):
|
if re.search('[^a-zA-Z0-9]', token):
|
||||||
return _get_new_csrf_token()
|
return _get_new_csrf_token()
|
||||||
elif len(token) == CSRF_TOKEN_LENGTH:
|
elif len(token) == CSRF_TOKEN_LENGTH:
|
||||||
return token
|
return token
|
||||||
|
@ -238,11 +237,7 @@ class CsrfViewMiddleware(MiddlewareMixin):
|
||||||
# Barth et al. found that the Referer header is missing for
|
# Barth et al. found that the Referer header is missing for
|
||||||
# same-domain requests in only about 0.2% of cases or less, so
|
# same-domain requests in only about 0.2% of cases or less, so
|
||||||
# we can use strict Referer checking.
|
# we can use strict Referer checking.
|
||||||
referer = force_text(
|
referer = request.META.get('HTTP_REFERER')
|
||||||
request.META.get('HTTP_REFERER'),
|
|
||||||
strings_only=True,
|
|
||||||
errors='replace'
|
|
||||||
)
|
|
||||||
if referer is None:
|
if referer is None:
|
||||||
return self._reject(request, REASON_NO_REFERER)
|
return self._reject(request, REASON_NO_REFERER)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import itertools
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.middleware.csrf import get_token
|
from django.middleware.csrf import get_token
|
||||||
from django.utils.encoding import force_text
|
|
||||||
from django.utils.functional import SimpleLazyObject, lazy
|
from django.utils.functional import SimpleLazyObject, lazy
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,7 +27,7 @@ def csrf(request):
|
||||||
# instead of returning an empty dict.
|
# instead of returning an empty dict.
|
||||||
return 'NOTPROVIDED'
|
return 'NOTPROVIDED'
|
||||||
else:
|
else:
|
||||||
return force_text(token)
|
return token
|
||||||
|
|
||||||
return {'csrf_token': SimpleLazyObject(_get_val)}
|
return {'csrf_token': SimpleLazyObject(_get_val)}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import warnings
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
@ -12,7 +11,6 @@ from django.middleware.csrf import (
|
||||||
)
|
)
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase, override_settings
|
||||||
from django.test.utils import patch_logger
|
from django.test.utils import patch_logger
|
||||||
from django.utils.encoding import force_bytes
|
|
||||||
from django.views.decorators.csrf import csrf_exempt, requires_csrf_token
|
from django.views.decorators.csrf import csrf_exempt, requires_csrf_token
|
||||||
|
|
||||||
from .views import (
|
from .views import (
|
||||||
|
@ -202,7 +200,7 @@ class CsrfViewMiddlewareTestMixin:
|
||||||
A new token is sent if the csrf_cookie is the empty string.
|
A new token is sent if the csrf_cookie is the empty string.
|
||||||
"""
|
"""
|
||||||
req = self._get_GET_no_csrf_cookie_request()
|
req = self._get_GET_no_csrf_cookie_request()
|
||||||
req.COOKIES[settings.CSRF_COOKIE_NAME] = b""
|
req.COOKIES[settings.CSRF_COOKIE_NAME] = ""
|
||||||
CsrfViewMiddleware().process_view(req, token_view, (), {})
|
CsrfViewMiddleware().process_view(req, token_view, (), {})
|
||||||
resp = token_view(req)
|
resp = token_view(req)
|
||||||
|
|
||||||
|
@ -303,7 +301,7 @@ class CsrfViewMiddlewareTestMixin:
|
||||||
response = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
|
response = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
|
||||||
self.assertContains(response, malformed_referer_msg, status_code=403)
|
self.assertContains(response, malformed_referer_msg, status_code=403)
|
||||||
# Non-ASCII
|
# Non-ASCII
|
||||||
req.META['HTTP_REFERER'] = b'\xd8B\xf6I\xdf'
|
req.META['HTTP_REFERER'] = 'ØBöIß'
|
||||||
response = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
|
response = CsrfViewMiddleware().process_view(req, post_form_view, (), {})
|
||||||
self.assertContains(response, malformed_referer_msg, status_code=403)
|
self.assertContains(response, malformed_referer_msg, status_code=403)
|
||||||
# missing scheme
|
# missing scheme
|
||||||
|
@ -566,24 +564,6 @@ class CsrfViewMiddlewareTests(CsrfViewMiddlewareTestMixin, SimpleTestCase):
|
||||||
csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
|
csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
|
||||||
self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH)
|
self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH)
|
||||||
|
|
||||||
def test_process_view_token_invalid_bytes(self):
|
|
||||||
"""
|
|
||||||
If the token contains improperly encoded unicode, it is ignored and a
|
|
||||||
new token is created.
|
|
||||||
"""
|
|
||||||
token = (b"<1>\xc2\xa1" + force_bytes(self._csrf_id, 'ascii'))[:CSRF_TOKEN_LENGTH]
|
|
||||||
req = self._get_GET_no_csrf_cookie_request()
|
|
||||||
req.COOKIES[settings.CSRF_COOKIE_NAME] = token
|
|
||||||
# We expect a UnicodeWarning here, because we used broken utf-8 on purpose
|
|
||||||
with warnings.catch_warnings():
|
|
||||||
warnings.filterwarnings("ignore", category=UnicodeWarning)
|
|
||||||
CsrfViewMiddleware().process_view(req, token_view, (), {})
|
|
||||||
resp = token_view(req)
|
|
||||||
resp2 = CsrfViewMiddleware().process_response(req, resp)
|
|
||||||
csrf_cookie = resp2.cookies.get(settings.CSRF_COOKIE_NAME, False)
|
|
||||||
self.assertEqual(len(csrf_cookie.value), CSRF_TOKEN_LENGTH)
|
|
||||||
self.assertNotEqual(csrf_cookie.value, token)
|
|
||||||
|
|
||||||
def test_process_view_token_invalid_chars(self):
|
def test_process_view_token_invalid_chars(self):
|
||||||
"""
|
"""
|
||||||
If the token contains non-alphanumeric characters, it is ignored and a
|
If the token contains non-alphanumeric characters, it is ignored and a
|
||||||
|
|
Loading…
Reference in New Issue