如何从Sentry错误报告中过滤敏感的Django POST参数?

时间:2014-05-22 15:53:18

标签: django heroku error-reporting sentry sensitive-data

引用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'])
  

在上面的示例中,pass_word和credit_card_number POST参数的值将被隐藏,并在错误报告中的请求表示中替换为星号( ****** ),而name参数的值将被公开。

     

要在错误报告中系统地隐藏请求的所有POST参数,请不要向sensitive_post_parameters装饰器提供任何参数:

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

作为测试,我将以下代码添加到我的Django 1.6应用程序中:

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)

当我通过POST提交此表单时,我可以看到这两个字段的值(包括sensitive)在Sentry报告中显示为日期。

我在这里做错了什么?我正在使用Django 1.6和Raven 3.5.2。

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

事实证明,这源于Django本身的一个错误!

如果您未在settings文件中更改DEFAULT_EXCEPTION_REPORTER_FILTER,则会获得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 for Django时会遇到这个问题,因为事实证明Raven DjangoClient的{​​{3}}方法首先尝试获取请求' s {来自POST的{​​1}}参数:

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