Closed judgej closed 5 years ago
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
).
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.
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
.
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.
@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:
.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.
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
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...
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.
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.
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.
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?