mirror of
https://github.com/django/django.git
synced 2025-01-22 00:02:15 +00:00
Fixed #33606 -- Cleansed sessionid cookie in error reports.
Co-authored-by: Simon Charette <charette.s@gmail.com>
This commit is contained in:
parent
b440493eaa
commit
350455b666
@ -110,7 +110,7 @@ class SafeExceptionReporterFilter:
|
|||||||
|
|
||||||
cleansed_substitute = "********************"
|
cleansed_substitute = "********************"
|
||||||
hidden_settings = _lazy_re_compile(
|
hidden_settings = _lazy_re_compile(
|
||||||
"API|TOKEN|KEY|SECRET|PASS|SIGNATURE", flags=re.I
|
"API|TOKEN|KEY|SECRET|PASS|SIGNATURE|HTTP_COOKIE", flags=re.I
|
||||||
)
|
)
|
||||||
|
|
||||||
def cleanse_setting(self, key, value):
|
def cleanse_setting(self, key, value):
|
||||||
@ -118,10 +118,13 @@ class SafeExceptionReporterFilter:
|
|||||||
Cleanse an individual setting key/value of sensitive content. If the
|
Cleanse an individual setting key/value of sensitive content. If the
|
||||||
value is a dictionary, recursively cleanse the keys in that dictionary.
|
value is a dictionary, recursively cleanse the keys in that dictionary.
|
||||||
"""
|
"""
|
||||||
try:
|
if key == settings.SESSION_COOKIE_NAME:
|
||||||
is_sensitive = self.hidden_settings.search(key)
|
is_sensitive = True
|
||||||
except TypeError:
|
else:
|
||||||
is_sensitive = False
|
try:
|
||||||
|
is_sensitive = self.hidden_settings.search(key)
|
||||||
|
except TypeError:
|
||||||
|
is_sensitive = False
|
||||||
|
|
||||||
if is_sensitive:
|
if is_sensitive:
|
||||||
cleansed = self.cleansed_substitute
|
cleansed = self.cleansed_substitute
|
||||||
@ -158,6 +161,14 @@ class SafeExceptionReporterFilter:
|
|||||||
return {}
|
return {}
|
||||||
return {k: self.cleanse_setting(k, v) for k, v in request.META.items()}
|
return {k: self.cleanse_setting(k, v) for k, v in request.META.items()}
|
||||||
|
|
||||||
|
def get_safe_cookies(self, request):
|
||||||
|
"""
|
||||||
|
Return a dictionary of request.COOKIES with sensitive values redacted.
|
||||||
|
"""
|
||||||
|
if not hasattr(request, "COOKIES"):
|
||||||
|
return {}
|
||||||
|
return {k: self.cleanse_setting(k, v) for k, v in request.COOKIES.items()}
|
||||||
|
|
||||||
def is_active(self, request):
|
def is_active(self, request):
|
||||||
"""
|
"""
|
||||||
This filter is to add safety in production environments (i.e. DEBUG
|
This filter is to add safety in production environments (i.e. DEBUG
|
||||||
@ -359,6 +370,7 @@ class ExceptionReporter:
|
|||||||
"frames": frames,
|
"frames": frames,
|
||||||
"request": self.request,
|
"request": self.request,
|
||||||
"request_meta": self.filter.get_safe_request_meta(self.request),
|
"request_meta": self.filter.get_safe_request_meta(self.request),
|
||||||
|
"request_COOKIES_items": self.filter.get_safe_cookies(self.request).items(),
|
||||||
"user_str": user_str,
|
"user_str": user_str,
|
||||||
"filtered_POST_items": list(
|
"filtered_POST_items": list(
|
||||||
self.filter.get_post_parameters(self.request).items()
|
self.filter.get_post_parameters(self.request).items()
|
||||||
@ -376,7 +388,6 @@ class ExceptionReporter:
|
|||||||
if self.request is not None:
|
if self.request is not None:
|
||||||
c["request_GET_items"] = self.request.GET.items()
|
c["request_GET_items"] = self.request.GET.items()
|
||||||
c["request_FILES_items"] = self.request.FILES.items()
|
c["request_FILES_items"] = self.request.FILES.items()
|
||||||
c["request_COOKIES_items"] = self.request.COOKIES.items()
|
|
||||||
c["request_insecure_uri"] = self._get_raw_insecure_uri()
|
c["request_insecure_uri"] = self._get_raw_insecure_uri()
|
||||||
c["raising_view_name"] = get_caller(self.request)
|
c["raising_view_name"] = get_caller(self.request)
|
||||||
|
|
||||||
|
@ -281,7 +281,11 @@ following attributes and methods:
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
re.compile(r'API|TOKEN|KEY|SECRET|PASS|SIGNATURE', flags=re.IGNORECASE)
|
re.compile(r'API|TOKEN|KEY|SECRET|PASS|SIGNATURE|HTTP_COOKIE', flags=re.IGNORECASE)
|
||||||
|
|
||||||
|
.. versionchanged:: 4.2
|
||||||
|
|
||||||
|
``HTTP_COOKIE`` was added.
|
||||||
|
|
||||||
.. method:: is_active(request)
|
.. method:: is_active(request)
|
||||||
|
|
||||||
|
@ -176,6 +176,9 @@ Forms
|
|||||||
* :func:`~django.forms.models.modelform_factory` now respects the
|
* :func:`~django.forms.models.modelform_factory` now respects the
|
||||||
``formfield_callback`` attribute of the ``form``’s ``Meta``.
|
``formfield_callback`` attribute of the ``form``’s ``Meta``.
|
||||||
|
|
||||||
|
* Session cookies are now treated as credentials and therefore hidden and
|
||||||
|
replaced with stars (``**********``) in error reports.
|
||||||
|
|
||||||
Generic Views
|
Generic Views
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -1696,6 +1696,12 @@ class ExceptionReporterFilterTests(
|
|||||||
)
|
)
|
||||||
self.assertNotIn(b"super_secret", response.content)
|
self.assertNotIn(b"super_secret", response.content)
|
||||||
|
|
||||||
|
@override_settings(SESSION_COOKIE_NAME="djangosession")
|
||||||
|
def test_cleanse_session_cookie_value(self):
|
||||||
|
self.client.cookies.load({"djangosession": "should not be displayed"})
|
||||||
|
response = self.client.get("/raises500/")
|
||||||
|
self.assertNotContains(response, "should not be displayed", status_code=500)
|
||||||
|
|
||||||
|
|
||||||
class CustomExceptionReporterFilter(SafeExceptionReporterFilter):
|
class CustomExceptionReporterFilter(SafeExceptionReporterFilter):
|
||||||
cleansed_substitute = "XXXXXXXXXXXXXXXXXXXX"
|
cleansed_substitute = "XXXXXXXXXXXXXXXXXXXX"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user