Django error messages: env vars leak info

The built-in Django function for emailing admins with errors (see https://docs.djangoproject.com/en/dev/howto/error-reporting/ ) is very convenient.

However, these trace messages include a complete dump of environment variables.

And as stated in django docs and elsewhere (e.g. https://docs.djangoproject.com/en/dev/howto/deployment/checklist/ ), I moved some secrets / keys / passwords to environment variables as an easy way to save them from the code base and change them in all deployments. Unfortunately, this means that when there is a crash report, these secrets are sent to the email account set box. Not a good practice.

django ExceptionReporter has basic filtering to pull out “dangerous or offensive” settings, for example, the value of any element in settings.py whose name contains the string “pass” or “key” will be replaced with **** s. Thus, the secret key in settings.py gets edited. But this filter does not apply to environment variables that appear in the Traceback-> Local vars-> request and Request Information-> Meta sections of these error reports.

Obviously, there are other ways to manage secrets, but the unix environment is a fairly common solution for small sites where creating a more complex configuration system is not justified.

It also seems problematic that these two practices recommended in the django core docs are unsafe to use together.

Emailing site debugging information always carries some risk of information leakage, but this seems like a significant omission that can be addressed by advanced filtering, possibly controlled by some settings.

Has anyone already fixed this (supposedly expanded the filtering in django / views / debug.py) to deploy them and / or sent a patch to the django command? Or did I miss another obvious way to solve this problem?

+7
python django logging environment-variables
source share
4 answers

OK, I skipped this in my previous check, but apparently the django team spent about this error and closed it as a non-fix 6 years ago:

https://code.djangoproject.com/ticket/7472

I agree with them, since I believe that django has made significant progress in the field of security over the past time and now may want to ask for some simple ways to solve this problem. :)

In the meantime, if you use this email-the-admins function, please review the risks. If you send these letters, I highly recommend that you leave or put all the secrets / passwords / keys / certificates / etc in the python configuration files and make sure that you clean the environment (unix) that is passed to your django web service.

+3
source share

I ran into the same problem and turned to it, creating my own middleware, as described in the Django docs . This approach assumes that you know the names of the env variables that you want to hide from the error / email pages, and that you really do not need these variables that are present in every request. You can then filter them out of the request.META dictionary until you get an error response:

class RequestSafetyMiddleware(object): def __init__(self, get_response): self.get_response = get_response def __call__(self, request): request.META.pop('TOP_SECRET', None) response = self.get_response(request) return response 

Hope this helps! I want Django to apply the same security obfuscation rules for env variables as it does for settings, so this is not even a problem.

+1
source share

This type of problem applies to all applications that relate to potentially sensitive information. An error message from such an application is likely to lead to leakage of confidential information if the error reporting system does not create a confidentiality mechanism (in most cases), which, apparently, refers to Django.

Confidentiality protection when error messages fail can be achieved using dedicated solutions, for example:

http://www.gsd.inesc-id.pt/~romanop/files/papers/ESOP14.pdf

http://research.microsoft.com/en-us/projects/betterbug/castro08better.pdf

These systems can be integrated with error reporting systems to ensure that the contents of error reports are sanitized before requesting permission from the user to transmit it.

In the next few months, new work will appear, which will include open source versions. I will update this message when they appear.

Hope this helps.

0
source share

In the case of using mod_wsgi with Apache, environment variables (set in the Apache SetEnv directive or otherwise) are passed to the application function in the first argument of environ .

To have access to these environment variables in settings.py (or elsewhere), it is convenient to copy them to os.environ , using, for example,

 os.environ['TOP_SECRET'] = environ['TOP_SECRET'] 

After this environ is passed to django.core.handlers.wsgi.WSGIHandler (via django.core.wsgi.get_wsgi_application ), where it ultimately makes a path to error reporting.

The TOP_SECRET key TOP_SECRET not need to be saved in environ after it is copied to os.environ , therefore changing the line above to os.environ['TOP_SECRET'] = environ.pop('TOP_SECRET', '') removes it from the error reports.

wsgi.py it all together, my wsgi.py file looks like this:

 import os from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "App.settings") env_variables_to_pass = ['TOP_SECRET'] def application(environ, start_response): # pass the WSGI environment variables on through to os.environ for var in env_variables_to_pass: os.environ[var] = environ.pop(var, '') return get_wsgi_application()(environ, start_response) 

This means that the required environment variables are available in os.environ where necessary, but they do not appear in error reports.

It is possible that I missed something, but it seems to work for me. If there is a reason not to do this, post a comment. It may be safer to first create a copy of the environ dictionary, i.e. my_environ = copy.deepcopy(environ) and then use instead of environ .

Note also that other sensitive variables (e.g. passwords in POST requests) must be filtered out .

0
source share

All Articles