Fixed #23004 -- Added request.META filtering to SafeExceptionReporterFilter.

Co-authored-by: Ryan Castner <castner.rr@gmail.com>
This commit is contained in:
Carlton Gibson 2020-01-09 11:37:19 +01:00 committed by Mariusz Felisiak
parent 581ba5a948
commit e2d9d66a22
6 changed files with 40 additions and 7 deletions

View File

@ -123,6 +123,14 @@ class SafeExceptionReporterFilter(ExceptionReporterFilter):
settings_dict[k] = self.cleanse_setting(k, getattr(settings, k))
return settings_dict
def get_safe_request_meta(self, request):
"""
Return a dictionary of request.META with sensitive values redacted.
"""
if not hasattr(request, 'META'):
return {}
return {k: self.cleanse_setting(k, v) for k, v in request.META.items()}
def is_active(self, request):
"""
This filter is to add safety in production environments (i.e. DEBUG
@ -296,6 +304,7 @@ class ExceptionReporter:
'unicode_hint': unicode_hint,
'frames': frames,
'request': self.request,
'request_meta': self.filter.get_safe_request_meta(self.request),
'user_str': user_str,
'filtered_POST_items': list(self.filter.get_post_parameters(self.request).items()),
'settings': self.filter.get_safe_settings(),

View File

@ -438,7 +438,7 @@ Exception Value: {{ exception_value|force_escape }}
</tr>
</thead>
<tbody>
{% for var in request.META.items|dictsort:0 %}
{% for var in request_meta.items|dictsort:0 %}
<tr>
<td>{{ var.0 }}</td>
<td class="code"><pre>{{ var.1|pprint }}</pre></td>

View File

@ -50,7 +50,7 @@ FILES:{% for k, v in request_FILES_items %}
COOKIES:{% for k, v in request_COOKIES_items %}
{{ k }} = {{ v|stringformat:"r" }}{% empty %} No cookie data{% endfor %}
META:{% for k, v in request.META.items|dictsort:0 %}
META:{% for k, v in request_meta.items|dictsort:0 %}
{{ k }} = {{ v|stringformat:"r" }}{% endfor %}
{% else %}Request data not supplied
{% endif %}

View File

@ -277,8 +277,9 @@ following attributes and methods:
.. versionadded:: 3.1
A compiled regular expression object used to match settings considered
as sensitive. By default equivalent to::
A compiled regular expression object used to match settings and
``request.META`` values considered as sensitive. By default equivalent
to::
import re
@ -289,8 +290,9 @@ following attributes and methods:
Returns ``True`` to activate the filtering in
:meth:`get_post_parameters` and :meth:`get_traceback_frame_variables`.
By default the filter is active if :setting:`DEBUG` is ``False``. Note
that sensitive settings are always filtered, as described in the
:setting:`DEBUG` documentation.
that sensitive ``request.META`` values are always filtered along with
sensitive setting values, as described in the :setting:`DEBUG`
documentation.
.. method:: get_post_parameters(request)

View File

@ -161,9 +161,13 @@ Email
Error Reporting
~~~~~~~~~~~~~~~
* :class:`django.views.debug.SafeExceptionReporterFilter` now filters sensitive
values from ``request.META`` in exception reports.
* The new :attr:`.SafeExceptionReporterFilter.cleansed_substitute` and
:attr:`.SafeExceptionReporterFilter.hidden_settings` attributes allow
customization of sensitive settings filtering in exception reports.
customization of sensitive settings and ``request.META`` filtering in
exception reports.
* The technical 404 debug view now respects
:setting:`DEFAULT_EXCEPTION_REPORTER_FILTER` when applying settings

View File

@ -1224,6 +1224,24 @@ class ExceptionReporterFilterTests(ExceptionReportTestMixin, LoggingCaptureMixin
{'login': 'cooper', 'password': reporter_filter.cleansed_substitute},
)
def test_request_meta_filtering(self):
request = self.rf.get('/', HTTP_SECRET_HEADER='super_secret')
reporter_filter = SafeExceptionReporterFilter()
self.assertEqual(
reporter_filter.get_safe_request_meta(request)['HTTP_SECRET_HEADER'],
reporter_filter.cleansed_substitute,
)
def test_exception_report_uses_meta_filtering(self):
response = self.client.get('/raises500/', HTTP_SECRET_HEADER='super_secret')
self.assertNotIn(b'super_secret', response.content)
response = self.client.get(
'/raises500/',
HTTP_SECRET_HEADER='super_secret',
HTTP_X_REQUESTED_WITH='XMLHttpRequest',
)
self.assertNotIn(b'super_secret', response.content)
class CustomExceptionReporterFilter(SafeExceptionReporterFilter):
cleansed_substitute = 'XXXXXXXXXXXXXXXXXXXX'