Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why read_env reads everything to os.environ? #66

Closed
sirex opened this issue Dec 28, 2015 · 5 comments
Closed

Why read_env reads everything to os.environ? #66

sirex opened this issue Dec 28, 2015 · 5 comments
Labels
question Further information is requested

Comments

@sirex
Copy link
Contributor

sirex commented Dec 28, 2015

It looks quite suspicious that everything is read into global variable environ.Env.ENVIRON and even worse, environ.Env.ENVIRON points to os.eviron.

For global variables, if I will instantiate environ.Env two times, I would expect to get two independent environments, but currently, I will have two class instances operating on same global environment.

Is there a good reason for this?

@sirex sirex changed the title Why read Why read_env reads everything to os.environ? Dec 28, 2015
@joke2k
Copy link
Owner

joke2k commented Dec 29, 2015

The main reason is that this package helps you to interact with os.environ,
loading values (from .env file) and parsing them.
You are right when say that two instances of environ.Env not produce two different environments, but it is by design.

An evolution of this package can support it, loading values from a cascade list of sources, producing different environments replacing the use of os.enrivon.

Why do you call suspicious a simple wrapper for os.environ?

@joke2k joke2k added the question Further information is requested label Dec 29, 2015
@sirex
Copy link
Contributor Author

sirex commented Dec 29, 2015

@joke2k thank you for explanation. It looked suspicious at first because environ.Env does not looked like a wrapper around os.environ, I assumed, that this is some kind of internal environment for configuration variables, that takes values from both os.environ and .env file.

Saving everything to os.environ seems dangerous, because it can easily effect whole behaviour of python by overriding one of PYTHON* environment variables and potentially could leak sensitive data.

Using os.environ as a storage for configuration variables looks unsafe, because environment variables can be accessed in many ways and potentially could leak sensitive information, like SECRET_KEY. So having possibility to explicitly control what is stored into os.environ would protect configuration values form potential exposure.

From what I understand, currently there is no direct use of os.environ values put by django-environ? I mean if environ.Env.ENVIRON would be changed to an instance attribute, everything would work as before?

@joke2k
Copy link
Owner

joke2k commented Dec 29, 2015

There is only one case in which django-environ put some data into os.environ,
when you run environ.Env.read_env().
In that case the security problem is related to the security on .env file.

I don't know if there are more secure way to pass some data to django settings, but i read a lot of articles that use environment variables to do that, including all the cloud hosting mazinga providers like Amazon or Heroku.

Also reading the 12factor.net/config:

The twelve-factor app stores config in environment variables (often shortened to env vars or env). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard.

@sirex
Copy link
Contributor Author

sirex commented Dec 29, 2015

Sure, environment variables are really convenient way to pass configuration options between processes. But once configuration value gets into a process, then inside process itself there is no need to expose them as environment variables, unless you need it for some reason.

My point is, that it is really good to be able to override configuration values with environment variables, but not store everything from .env as environment variables to be passed further.

If you keep everything in os.environ, it means, this value could be exposed to other processes making more copies of sensitive data. One good example is Django traceback page when DEBUG = True, in that page SECRET_KEY coming from settings is hidden, but in environment variables table it is shown in plain text, same thing in debug toolbar. Also all os.environ is copies to request.META. Also environment variables can be accessed from /proc/<pid>/environ.

So if I put a secret in .env file and make sure that file permissions are secure, I would like to know, that this is the only place where my secret is exposed. But since everything goes from .env to environment variables, then there are many places when my secret can be exposed and making sure that everything is secure is much harder.

Anyway, I'm not security expert, just have a suspicion, that using os.environ as configuration storage can have unexpected consequences. Closing this issue for now, until someone with better knowledge could explain if it is bad idea so save .env to os.environ.

@sirex sirex closed this as completed Dec 29, 2015
@joke2k
Copy link
Owner

joke2k commented Dec 29, 2015

The security is a myth 😄

I've checked all my servers to see permissions of /proc/<pid>/environ and they are only-read for process owner, like my .env file. 😅

Anyway, Thank you for questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants