Opened 8 years ago
Last modified 4 months ago
#28215 assigned Bug
sensitive_post_parameters/sensitive_variables leaking sensitive values into the http 500 exception email — at Initial Version
Description ¶
tl;dr ¶
despite using sensitive_xxx decorator, sensitive data can end up in the 500 error emails Django sends, as these decorators only protect the data inside the very function they are decorated
repro ¶
Is attached for all current supported Django versions (1.8, 1.10, 1.11), simply unpack and run tox
(https://gist.github.com/zsoldosp/1cc4c922e8aa925439516b0c127e70d6 - this is the first time I'm trying to attach files, thus including a link to a gist as a backup if that doesn't work)
The test can seem complicated due to the limitations of the test client in testing 500 responses - see #18707
why I think it is an issue ¶
While I'm aware of the [disclaimers in the documentation about filtering sensitive data (https://docs.djangoproject.com/en/1.8/howto/error-reporting/#custom-error-reports), because of the impact of it - even on users who don't explicitly use any of the sensitive_x
decorators themselves, I think it is a leak that should be stopped.
- typical sensitive data is passwords. We have discovered this issue due to a bug in our custom authentication backend. These passwords could also be used beyond just the single Django system - whether because of single sign on solutions like LDAP/active-directory, or simply because users might reuse their passwords across sites
- exception emails might be sent through third party providers, which may keep track of the sent message body. Internal IT departments might also be considered such 3rd parties too.
- support people (admins receiving 500 emails) see supposedly private data
potential solution ideas (which might be wrong of course :)) ¶
writing a custom exception filter ¶
- simply don't report any variables once encountered - https://gist.github.com/zsoldosp/5710abaa9dedc03417d60bcc714c95d4
- keep track of protected variable names and replace those in frames further down the stack (i.e.: if parameter 'password', is sensitive, cleanse variables names 'password' too in all methods)
wrapping sensitive variables into a special object ¶
Instead of just using the sensitive data in reporting, wrap these variables in an object that has 'contains_sensitive_data' attribute, i.e.: if it is stored into another variable, as it is a 'pointer' to the original, it will have that attribute, and thus can be filtered out in the exception report.
This isn't perfect either, e.g.: password = password.strip()
, though by overriding a lot of methods or using __getattr__
magic, it could work. Might only be 'reasonable' to do so for request parameters, as there at least we know the limited set of variable types we receive
@sensitive_request_params def view(request): .... # inside sensitive_request_params for sensitive_variable_name in sensitive_variable_names: if sensitive_variable_name in request.POST: request.POST[sensitive_variable_name] = SensitiveVariable(request.POST[sensitive_variable_name]) ....
According to the ticket's flags, the next step(s) to move this issue forward are:
- To provide a patch by sending a pull request. Claim the ticket when you start working so that someone else doesn't duplicate effort. Before sending a pull request, review your work against the patch review checklist. Check the "Has patch" flag on the ticket after sending a pull request and include a link to the pull request in the ticket comment when making that update. The usual format is:
[https://github.com/django/django/pull/#### PR]
.
a minimal tox.ini/django project to repro the case