mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
[1.6.x] Fixed #21098 -- Applied sensitive_post_parameters to MultiValueDict
Thanks simonpercivall for the report and bmispelon for the review.
Backport of 2daada800f from master
This commit is contained in:
@@ -11,6 +11,7 @@ from django.http import (HttpResponse, HttpResponseServerError,
|
||||
HttpResponseNotFound, HttpRequest, build_request_repr)
|
||||
from django.template import Template, Context, TemplateDoesNotExist
|
||||
from django.template.defaultfilters import force_escape, pprint
|
||||
from django.utils.datastructures import MultiValueDict
|
||||
from django.utils.html import escape
|
||||
from django.utils.encoding import force_bytes, smart_text
|
||||
from django.utils.module_loading import import_by_path
|
||||
@@ -118,6 +119,20 @@ class SafeExceptionReporterFilter(ExceptionReporterFilter):
|
||||
"""
|
||||
return settings.DEBUG is False
|
||||
|
||||
def get_cleansed_multivaluedict(self, request, multivaluedict):
|
||||
"""
|
||||
Replaces the keys in a MultiValueDict marked as sensitive with stars.
|
||||
This mitigates leaking sensitive POST parameters if something like
|
||||
request.POST['nonexistent_key'] throws an exception (#21098).
|
||||
"""
|
||||
sensitive_post_parameters = getattr(request, 'sensitive_post_parameters', [])
|
||||
if self.is_active(request) and sensitive_post_parameters:
|
||||
multivaluedict = multivaluedict.copy()
|
||||
for param in sensitive_post_parameters:
|
||||
if param in multivaluedict:
|
||||
multivaluedict[param] = CLEANSED_SUBSTITUTE
|
||||
return multivaluedict
|
||||
|
||||
def get_post_parameters(self, request):
|
||||
"""
|
||||
Replaces the values of POST parameters marked as sensitive with
|
||||
@@ -143,6 +158,15 @@ class SafeExceptionReporterFilter(ExceptionReporterFilter):
|
||||
else:
|
||||
return request.POST
|
||||
|
||||
def cleanse_special_types(self, request, value):
|
||||
if isinstance(value, HttpRequest):
|
||||
# Cleanse the request's POST parameters.
|
||||
value = self.get_request_repr(value)
|
||||
elif isinstance(value, MultiValueDict):
|
||||
# Cleanse MultiValueDicts (request.POST is the one we usually care about)
|
||||
value = self.get_cleansed_multivaluedict(request, value)
|
||||
return value
|
||||
|
||||
def get_traceback_frame_variables(self, request, tb_frame):
|
||||
"""
|
||||
Replaces the values of variables marked as sensitive with
|
||||
@@ -173,17 +197,14 @@ class SafeExceptionReporterFilter(ExceptionReporterFilter):
|
||||
for name, value in tb_frame.f_locals.items():
|
||||
if name in sensitive_variables:
|
||||
value = CLEANSED_SUBSTITUTE
|
||||
elif isinstance(value, HttpRequest):
|
||||
# Cleanse the request's POST parameters.
|
||||
value = self.get_request_repr(value)
|
||||
else:
|
||||
value = self.cleanse_special_types(request, value)
|
||||
cleansed[name] = value
|
||||
else:
|
||||
# Potentially cleanse only the request if it's one of the frame variables.
|
||||
# Potentially cleanse the request and any MultiValueDicts if they
|
||||
# are one of the frame variables.
|
||||
for name, value in tb_frame.f_locals.items():
|
||||
if isinstance(value, HttpRequest):
|
||||
# Cleanse the request's POST parameters.
|
||||
value = self.get_request_repr(value)
|
||||
cleansed[name] = value
|
||||
cleansed[name] = self.cleanse_special_types(request, value)
|
||||
|
||||
if (tb_frame.f_code.co_name == 'sensitive_variables_wrapper'
|
||||
and 'sensitive_variables_wrapper' in tb_frame.f_locals):
|
||||
|
||||
Reference in New Issue
Block a user