summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJulien Phalip <jphalip@gmail.com>2012-12-31 09:34:08 -0800
committerJulien Phalip <jphalip@gmail.com>2012-12-31 09:51:13 -0800
commitdfd8623de4e225e33c334086ff4e2ccdfb07247f (patch)
tree318b722bb3212031bfd33f0fb6bba9ed6415210e /tests
parentfd1279a44df3b9a837453cd79fd0fbcf81bae39d (diff)
[1.5.x] Fixed #19453 -- Ensured that the decorated function's arguments are obfuscated in the @sensitive_variables decorator's frame, in case the variables associated with those arguments were meant to be obfuscated from the decorated function's frame.
Thanks to vzima for the report. Backport of 9180146d21cf2a31eec
Diffstat (limited to 'tests')
-rw-r--r--tests/regressiontests/views/tests/debug.py92
-rw-r--r--tests/regressiontests/views/views.py33
2 files changed, 106 insertions, 19 deletions
diff --git a/tests/regressiontests/views/tests/debug.py b/tests/regressiontests/views/tests/debug.py
index 4fdaad5010..0e36948b98 100644
--- a/tests/regressiontests/views/tests/debug.py
+++ b/tests/regressiontests/views/tests/debug.py
@@ -7,7 +7,6 @@ import inspect
import os
import sys
-from django.conf import settings
from django.core import mail
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.urlresolvers import reverse
@@ -19,7 +18,8 @@ from django.views.debug import ExceptionReporter
from .. import BrokenException, except_args
from ..views import (sensitive_view, non_sensitive_view, paranoid_view,
- custom_exception_reporter_filter_view, sensitive_method_view)
+ custom_exception_reporter_filter_view, sensitive_method_view,
+ sensitive_args_function_caller, sensitive_kwargs_function_caller)
@override_settings(DEBUG=True, TEMPLATE_DEBUG=True)
@@ -306,17 +306,28 @@ class ExceptionReportTestMixin(object):
response = view(request)
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
+
# Frames vars are never shown in plain text email reports.
- body = force_text(email.body)
- self.assertNotIn('cooked_eggs', body)
- self.assertNotIn('scrambled', body)
- self.assertNotIn('sauce', body)
- self.assertNotIn('worcestershire', body)
+ body_plain = force_text(email.body)
+ self.assertNotIn('cooked_eggs', body_plain)
+ self.assertNotIn('scrambled', body_plain)
+ self.assertNotIn('sauce', body_plain)
+ self.assertNotIn('worcestershire', body_plain)
+
+ # Frames vars are shown in html email reports.
+ body_html = force_text(email.alternatives[0][0])
+ self.assertIn('cooked_eggs', body_html)
+ self.assertIn('scrambled', body_html)
+ self.assertIn('sauce', body_html)
+ self.assertIn('worcestershire', body_html)
+
if check_for_POST_params:
for k, v in self.breakfast_data.items():
# All POST parameters are shown.
- self.assertIn(k, body)
- self.assertIn(v, body)
+ self.assertIn(k, body_plain)
+ self.assertIn(v, body_plain)
+ self.assertIn(k, body_html)
+ self.assertIn(v, body_html)
def verify_safe_email(self, view, check_for_POST_params=True):
"""
@@ -328,22 +339,35 @@ class ExceptionReportTestMixin(object):
response = view(request)
self.assertEqual(len(mail.outbox), 1)
email = mail.outbox[0]
+
# Frames vars are never shown in plain text email reports.
- body = force_text(email.body)
- self.assertNotIn('cooked_eggs', body)
- self.assertNotIn('scrambled', body)
- self.assertNotIn('sauce', body)
- self.assertNotIn('worcestershire', body)
+ body_plain = force_text(email.body)
+ self.assertNotIn('cooked_eggs', body_plain)
+ self.assertNotIn('scrambled', body_plain)
+ self.assertNotIn('sauce', body_plain)
+ self.assertNotIn('worcestershire', body_plain)
+
+ # Frames vars are shown in html email reports.
+ body_html = force_text(email.alternatives[0][0])
+ self.assertIn('cooked_eggs', body_html)
+ self.assertIn('scrambled', body_html)
+ self.assertIn('sauce', body_html)
+ self.assertNotIn('worcestershire', body_html)
+
if check_for_POST_params:
for k, v in self.breakfast_data.items():
# All POST parameters' names are shown.
- self.assertIn(k, body)
+ self.assertIn(k, body_plain)
# Non-sensitive POST parameters' values are shown.
- self.assertIn('baked-beans-value', body)
- self.assertIn('hash-brown-value', body)
+ self.assertIn('baked-beans-value', body_plain)
+ self.assertIn('hash-brown-value', body_plain)
+ self.assertIn('baked-beans-value', body_html)
+ self.assertIn('hash-brown-value', body_html)
# Sensitive POST parameters' values are not shown.
- self.assertNotIn('sausage-value', body)
- self.assertNotIn('bacon-value', body)
+ self.assertNotIn('sausage-value', body_plain)
+ self.assertNotIn('bacon-value', body_plain)
+ self.assertNotIn('sausage-value', body_html)
+ self.assertNotIn('bacon-value', body_html)
def verify_paranoid_email(self, view):
"""
@@ -445,6 +469,36 @@ class ExceptionReporterFilterTests(TestCase, ExceptionReportTestMixin):
self.verify_safe_email(sensitive_method_view,
check_for_POST_params=False)
+ def test_sensitive_function_arguments(self):
+ """
+ Ensure that sensitive variables don't leak in the sensitive_variables
+ decorator's frame, when those variables are passed as arguments to the
+ decorated function.
+ Refs #19453.
+ """
+ with self.settings(DEBUG=True):
+ self.verify_unsafe_response(sensitive_args_function_caller)
+ self.verify_unsafe_email(sensitive_args_function_caller)
+
+ with self.settings(DEBUG=False):
+ self.verify_safe_response(sensitive_args_function_caller, check_for_POST_params=False)
+ self.verify_safe_email(sensitive_args_function_caller, check_for_POST_params=False)
+
+ def test_sensitive_function_keyword_arguments(self):
+ """
+ Ensure that sensitive variables don't leak in the sensitive_variables
+ decorator's frame, when those variables are passed as keyword arguments
+ to the decorated function.
+ Refs #19453.
+ """
+ with self.settings(DEBUG=True):
+ self.verify_unsafe_response(sensitive_kwargs_function_caller)
+ self.verify_unsafe_email(sensitive_kwargs_function_caller)
+
+ with self.settings(DEBUG=False):
+ self.verify_safe_response(sensitive_kwargs_function_caller, check_for_POST_params=False)
+ self.verify_safe_email(sensitive_kwargs_function_caller, check_for_POST_params=False)
+
class AjaxResponseExceptionReporterFilter(TestCase, ExceptionReportTestMixin):
"""
diff --git a/tests/regressiontests/views/views.py b/tests/regressiontests/views/views.py
index ed9d61144a..748f07637f 100644
--- a/tests/regressiontests/views/views.py
+++ b/tests/regressiontests/views/views.py
@@ -132,6 +132,7 @@ def send_log(request, exc_info):
][0]
orig_filters = admin_email_handler.filters
admin_email_handler.filters = []
+ admin_email_handler.include_html = True
logger.error('Internal Server Error: %s', request.path,
exc_info=exc_info,
extra={
@@ -184,6 +185,38 @@ def paranoid_view(request):
send_log(request, exc_info)
return technical_500_response(request, *exc_info)
+def sensitive_args_function_caller(request):
+ try:
+ sensitive_args_function(''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']))
+ except Exception:
+ exc_info = sys.exc_info()
+ send_log(request, exc_info)
+ return technical_500_response(request, *exc_info)
+
+@sensitive_variables('sauce')
+def sensitive_args_function(sauce):
+ # Do not just use plain strings for the variables' values in the code
+ # so that the tests don't return false positives when the function's source
+ # is displayed in the exception report.
+ cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd'])
+ raise Exception
+
+def sensitive_kwargs_function_caller(request):
+ try:
+ sensitive_kwargs_function(''.join(['w', 'o', 'r', 'c', 'e', 's', 't', 'e', 'r', 's', 'h', 'i', 'r', 'e']))
+ except Exception:
+ exc_info = sys.exc_info()
+ send_log(request, exc_info)
+ return technical_500_response(request, *exc_info)
+
+@sensitive_variables('sauce')
+def sensitive_kwargs_function(sauce=None):
+ # Do not just use plain strings for the variables' values in the code
+ # so that the tests don't return false positives when the function's source
+ # is displayed in the exception report.
+ cooked_eggs = ''.join(['s', 'c', 'r', 'a', 'm', 'b', 'l', 'e', 'd'])
+ raise Exception
+
class UnsafeExceptionReporterFilter(SafeExceptionReporterFilter):
"""
Ignores all the filtering done by its parent class.