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

Protection from exposing .env #64

Closed
judgej opened this issue May 11, 2017 · 10 comments
Closed

Protection from exposing .env #64

judgej opened this issue May 11, 2017 · 10 comments

Comments

@judgej
Copy link

judgej commented May 11, 2017

I noticed .env is in the same directory as index.php Many hosting services by default will display .env, and .git/ and other files and directories you would normally expect to be hidden.

Some protection can be put in using .htaccess, but I'm wondering what other measures are taken, planned or recommended?

@GaryJones
Copy link
Member

Some protection can be put in using .htaccess

Just for those who stumble over this ticket in the future, this is what I have in my htaccess:

# Stop browser-viewing of all files starting with a period.
<FilesMatch "^\.">
    Order allow,deny
    Deny from all
</FilesMatch>

@judgej Do you have any suggestions for other measures?

I think the .env might be readable from a directory up as well (if not, it should be) like wp-config.php can, but some folks are on hosting setups that don't allow that (lack of permissions, or one site being in a folder of another site which has its own .env).

@judgej
Copy link
Author

judgej commented May 11, 2017

I think it either needs to be a PHP script, or it should go into a directory with no web access at all. Mixing PHP scripts and important non-PHP config files that absolutely must not be exposed to the world in a single directory, is just asking for mistakes to happen. Most control panels allow you to protect a whole diectory fairly easily, for where .htaccess deny from all doesn't work.

The .env may or may not be reading if in the diectory above the public root. That depends on what security your hosting has, which should prevent your scripts from roaming around anywhere on the server outside of the web root, with the exception of /tmp.

The old problem of being able to cater for many hosting services - flexible and not - or defining some absolute requirements and leaving the end user to find appropriate hosting.

@GaryJones
Copy link
Member

How about a structure of:

- wp/
- wp-content/
- env/ (or rename to protected/private/config etc.)
- - .htaccess (protecting the file in here from being viewed in the browser)
- - .env.example
- .gitignore
- index.php
- wp-content.php

Code should be able to read from env/.env, or from /.env.

@judgej
Copy link
Author

judgej commented May 12, 2017

Definitely worth seeing how other projects do it. The general approaches are: keep it out of your web root, or hide it with .htaccess

http://stackoverflow.com/questions/33069319/env-file-is-visible

You can also set the variables up in other ways, as php.ini settings or simililar. The .env entries all ultimately just get set as global environment variables, which you can do before your WP script is run just as effectively as using dotenv to do it once your WP bootstrap starts running.

Maybe ,env should simply be out of the web root, and stated in capital letters in .env.example? Anyone not able to do that should either set up environment variables elsewhere (e.g. SentEnv in php.ini or .htaccess or whatever nginx uses) or put it into a hidden directory or hide the specific file. But those should probabty all be fallbacks if you can't locate it outside the web root.

Laravel handles this by supplying a public directory for the web root. It states that this is your web root, end of. You can move it around relative to the rest of the application, but they don't make any attempt to protect any other files in the project from direct web access other than by them not being under the web root.

@gmazzap
Copy link
Member

gmazzap commented May 13, 2017

@judgej

TL;DR Yes, you should definetively put .env file outside of the webroot.

Unfortunately, unlike Lavarel, we don't ship a complete system or a framework, we ships an installer for an application, WordPress, that is intended to be all put inside webroot.

The only files in WordPress that can be outside of webroot are wp-config.php and index.php and WP Starter uses this fact to install WordPress in a separate folder.

In the WP Starter documentation, the sample composer.json you can see here: https://github.com/wecodemore/wpstarter/blob/master/docs/complete-example.md uses WordPress installer to achieve a folder structure like this:

- /
  - composer.json
  - .env
  - /public     <-- webroot
    - /wp     <-- WordPress folder
    - /content     <-- custom content folder
    - index.php     <-- generated by WP Starter
    - wp-config.php     <-- generated by WP Starter

This is the suggested way to use WP Starter and it is the example composer.json in documentation for a reason.

However, this is only possible if you hosting allows you to put files up of webroot.

When that is not possible, something I successfully did in past is to create a subfolder in the webroot provided by hosting and then create a /public folder inside it to replicate the same folder tree as above and then ask the hosting to set the webroot to /public.

If even this is not an option, then there are 2 things left:

  • change hosting
  • use webserver configuration (e.g. .htaccess for Apache) to disable access to the file.

A thing that I always suggest is to remove permission to read/write/execute the file to anyone that is not the owner of the file, and ensure that the owbenrr is not the webserver user, this way even in case of some misconfiguration the file permission should prevent the file to be dumped on HTTP response.


On a side note, the absolutely best way to handle .env files in production is to don't have them at all.

Environment variables are a great solution because you can set them in the physical environment (e.g. via Apache SetEnv directive or nginx Env directive).

In fact, .env files are a way to emulate physical environment variables, but in production, when possible, one should use them instead of .env emulation: this is at same time safer and faster (no need for PHP loading and parsing .env files).

To be honest, current version of WP Starter (2.*) somehow relies on .env file, and the usage of physical environment variables is only possible hacking the WP Starter generated wp-config.php.

The main target for WP Starter 3 (in the work, but no ETA) will be to improve the workflow and to make usage of physical environment variables much easier.

@szepeviktor
Copy link

If you run your server this is the way to block access to non-entry-point WordPress files:
https://github.com/szepeviktor/debian-server-tools/blob/master/webserver/apache-conf-available/wordpress.inc.conf

@gmazzap
Copy link
Member

gmazzap commented Dec 23, 2017

That is assuming apache. Which I don't really want (personally I don't work in projects using apache since at least 3 years now).
The way to go is to put .env file outside of webroot, but that's something that should be done via server configuration not at application level...

@lkraav
Copy link
Contributor

lkraav commented Oct 27, 2018

I happened to come across this issue on a random "learn more" trip.

https://github.com/wecodemore/wpstarter/blob/master/docs/quick-start.md should probably have a mention about public .env dangers.

@gmazzap
Copy link
Member

gmazzap commented Nov 1, 2018

v3 docs have a very detailed explaination of the issue and how to overcome it.

But I should update also v2 docs, as this is security relevant.

@gmazzap
Copy link
Member

gmazzap commented Nov 1, 2018

I have "backported" documentation to v2. https://github.com/wecodemore/wpstarter/blob/master/docs/quick-start.md#important-security-issue-with-env-file I guess I can close this.

@gmazzap gmazzap closed this as completed Nov 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants