How to filter sensitive Django POST parameters from Sentry error reports?

To quote Django docs :

@sensitive_post_parameters('pass_word', 'credit_card_number')
def record_user_profile(request):
    UserProfile.create(user=request.user,
                       password=request.POST['pass_word'],
                       credit_card=request.POST['credit_card_number'],
                       name=request.POST['name'])

In the above example, the values ​​of the pass_word and credit_card_number POST parameters will be hidden and replaced with asterisks ( ****** ) in the query view inside the error reports, while the value of the name parameter will be expanded.

To systematically hide all POST request parameters in error reports, do not specify any arguments in decorator_post_parameters:

@sensitive_post_parameters()
def my_view(request):
    ...

As a test, I added the following code to the Django 1.6 application:

views.py:

@sensitive_post_parameters('sensitive')
def sensitive(request):
    if request.method == 'POST':
        raise IntegrityError(unicode(timezone.now()))
    return render(request, 'sensitive-test.html',
          {'form': forms.SensitiveParamForm()})

forms.py:

class SensitiveParamForm(forms.Form):
    not_sensitive = forms.CharField(max_length=255)
    sensitive = forms.CharField(max_length=255)

When I submit this form through POST, I can see the values ​​of both fields (including sensitive) as the day in the Sentry report.

? Django 1.6 Raven 3.5.2.

!

+4
1

, Django!

DEFAULT_EXCEPTION_REPORTER_FILTER settings, SafeExceptionReporterFilter.

sensitive_post_parameters, SafeExceptionReporterFilter get_post_parameters:

 def get_post_parameters(self, request):
        """
        Replaces the values of POST parameters marked as sensitive with
        stars (*********).
        """
        if request is None:
            return {}
        else:
            sensitive_post_parameters = getattr(request, 'sensitive_post_parameters', [])
            if self.is_active(request) and sensitive_post_parameters:
                cleansed = request.POST.copy()
                if sensitive_post_parameters == '__ALL__':
                    # Cleanse all parameters.
                    for k, v in cleansed.items():
                        cleansed[k] = CLEANSED_SUBSTITUTE
                    return cleansed
                else:
                    # Cleanse only the specified parameters.
                    for param in sensitive_post_parameters:
                        if param in cleansed:
                            cleansed[param] = CLEANSED_SUBSTITUTE
                    return cleansed
            else:
                return request.POST

, , QuerySet POST, CLEANSED_SUBSTITUTE ('********************')... , request.body.

Raven/Sentry Django, , get_data_from_request DjangoClient POST request.body:

def get_data_from_request(self, request):

  [snip]

    if request.method != 'GET':
        try:
            data = request.body
        except Exception:
            try:
                data = request.raw_post_data
            except Exception:
                # assume we had a partial read.
                try:
                    data = request.POST or '<unavailable>'
                except Exception:
                    data = '<unavailable>'
    else:
        data = None

 [snip]

DjangoClient QuerySet, SafeExceptionReporterFilter:

from django.views.debug import SafeExceptionReporterFilter
from raven.contrib.django.client import DjangoClient


class SafeDjangoClient(DjangoClient):

  def get_data_from_request(self, request):
    request.POST = SafeExceptionReporterFilter().get_post_parameters(request)
    result = super(SafeDjangoClient, self).get_data_from_request(request)
    result['sentry.interfaces.Http']['data'] = request.POST
    return result
+4

Source: https://habr.com/ru/post/1541639/