Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jlrdw's avatar
Level 75

env file

@Snapey in another post you gave this answer

You should ensure that /public/ does not appear in your URLs else your site will be vulnerable.

As far as I understand rewritebase just allows you to have .htaccess in the server root, and affect rewrites for another folder?

In your browser, check what happens with localhost/cheebamba/.env

Is this some sort of bug, shouldn't the env file be un-readable?

0 likes
19 replies
bashy's avatar

95% of people put the document root of their website (vhost) to the public folder. Some seem to think putting it to the root of Laravel files is okay and that a rewrite will suffice. If the htaccess file ever gets deleted or there's a config error, your files will be visible to the public internet.

Any file can be viewed or downloaded from the domain. If you protect against dot files, this is best practise. I wrote a blog post about it: https://bashy.im/blog/nginx-security-protect-htaccess-dot-and-dollar-sign-files

2 likes
Snapey's avatar

thanks @bashy. Indeed, plus if you want 'pretty urls' the public folder should be the root folder so that http://domain.com/ will load index.php.

all the files and folders above public will not be accessible.

jlrdw's avatar
Level 75

How would you handle this in apache? Also, if I type in.

localhost/Laravel/public/.env

I just get a route not found error, but.

localhost/Laravel/

Will bring up the folder/file listing and you can click on .env and it opens the file in wordpad. Not good.

jlrdw's avatar
Level 75

I found this on another post for apache

<FilesMatch "^\.">
    Order allow,deny
    Deny from all
</FilesMatch>

Does this go in the .conf file or .htaccess file?
And is the .env required on production server?

jekinney's avatar

When you type public/.env file you trigger the default htaccess and routes which by default .env file is not there anyways.

Best and easiest way imo is as @bashy hinted towards is your public file should be the only thing accessible by the outside world (why you put css, js, images etc in there) and why asset helper and url helper point to public folder by default.

Now forge sets this up for you when you deploy but if you deploy to say a shared hosting I would put everything except the public folder in the same file level as the www folder. And the contents of the public folder inside the www folder. Change the path that Laravel looks for the public folder accordingly and you should be set.

jlrdw's avatar
Level 75

@jekinney On one shared host I can't put the files there, What I tested on local is removing env like:
So from this

'mysql_bak' => [
            'driver'    => 'mysql',
            'host'      => env('DB_HOST', 'localhost'),
            'database'  => env('DB_DATABASE', 'forge'),
            'username'  => env('DB_USERNAME', 'forge'),
            'password'  => env('DB_PASSWORD', ''),
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ],

To

'mysql' => [
            'driver'    => 'mysql',
            'host'      => 'localhost',
            'database'  => 'pbackdate',
            'username'  => 'root',
            'password'  => '************',
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
        ],

Of course other files to like session, etc. Also deleted the .env file. This is working on local, do you think it will work on production?
I am not liking that .env thing.

bashy's avatar

If you don't like .env file you can use Apache (or php pool for nginx) to insert the variables for the site to PHP. The only reason you don't put them into config/database.php is because most of the time you will be using VC (version control). With VC you don't want other people to have to edit that config to match their dev setup (or have it in VC at all!).

Read up on how to add those vars into Apache and you'll be good.

jlrdw's avatar
Level 75

Thanks @bashy. I also found THE GUIDE that's referred from laravel news:
https://medium.com/laravel-news/the-simple-guide-to-deploy-laravel-5-application-on-shared-hosting-1a8d0aee923e and another technique from stackoverflow that works a little different, but does work: http://stackoverflow.com/questions/28364496/laravel-5-remove-public-from-url The last one is the one I used and works:



Rename the server.php in the your Laravel root folder to index.php and copy the .htaccess file from /public directory to your Laravel root folder. -- Thats it !! :)

That's working for me. But all resource files in /public directory couldn't find and request urls didn't work, because I used asset() helper.

I changed /Illuminate/Foundation/helpers.php/asset() function as follows:

function asset($path, $secure = null)
{
    return app('url')->asset("public/".$path, $secure);
}

Now everything works :)

The only other change I made is instead of loading an image like:

$picpath = "upload/";

I had to:

$picpath = "public/upload/";

so this would work

if (empty($row->dogpic)) {
                echo "<td>" . " " . "</td>";
            } else {
                //$picpath = "public/upload";
                $linev = "";
                $linev = "<td><a href=\"{$picpath}{$row->dogpic}\" target=\"_blank\">";
                $linev = $linev . "<img width=\"80\" border=\"0\"";
                $linev = $linev . "src=\"{$picpath}{$row->dogpic}\"></a></td>";
                echo $linev;
            }

I am going to try the other as well.
Edit: And thank you to everyone who replied.

jekinney's avatar

Another thing to do/check is file permissions if you can't put the files outside the root folder. They obviously need to exacute but read/write can be locked down.

jlrdw's avatar
Level 75

@jekinney, @bashy, @Snapey, and everyone I can't put the files outside the root folder. But after this http://stackoverflow.com/questions/28364496/laravel-5-remove-public-from-url I did more test. After making .env hidden, I found if I put localhost/myapp/.env in url, the env file is still readable to public. Discovered another work around in two files:

vendor\vlucas\phpdotenv\src\Dotenv.php  
and  
vendor\laravel\framework\src\Illuminate\Foundation\Application.php

After all is working, changing .env to env.php and of course in the above files
changing .env to env.php does the trick. A pain the first time, but now I can automate it.
Now htaccess is in root, no public in url, and people can't see the env information.
Would you trust this in a situation on a shared host where you can't move laravel up one?
It seems to work ok. I know I may disagree at times, but I still value your opinion and thoughts.
Side question, @jekinney are you retired Air Force, I am.
Edit: I know I don't have to use the .env, would you do it as above or just not use the .env, on this one host only? Or either?

Snapey's avatar

If your hosting provider does not permit files to be placed outside of the root, then an idea would be to find a different provider. Most do allow it and it saves all sorts of complications down the line. It doesn't matter what your public folder is called, nor does it matter if laravel is at the same level, eg:

/home
            /website
                           /wwwroot    (contents of your public folder)
                           /laravel    (content of the framework)

Put it to them - "hey, why can't I have private content...?"

Unfortunately you have a little task now in that you need to repatch your framework files next time there is an update.

jlrdw's avatar
Level 75

@Snapey but do yo think the patch works? The .env file was viewable by anyone til the patch.

Snapey's avatar

Well by renaming .env to .env.php means that the server will try and execute it rather than just dumping it to the browser.

There will be either nothing served, or more likely, an error thrown.

I'm not sure about the side-effects of renaming server.php to index.php. Certainly php Artisan serve won't work any more.

jlrdw's avatar
Level 75

I didn't get errors when testing. If it works in testing, do you think it would work on production site? Safe that is? In testing, I mean an actual site was ftp'ed tested and working, but not production, just test data, nothing secure.i

bashy's avatar

There's a lot of things to remember when deploying an app if you change all this...

Have you strongly considered switching to someone who knows how to setup/run a proper web hosting company? You should have SSH access with git/php and ability to install/run composer via that. You can fake the public folder with symlinks if you really can't change the document root or whatever. I used that method on one shared hosting configuration.

jlrdw's avatar
Level 75

@bashy you said

fake the public folder with symlinks 

Does this keep someone from typing

thesite/.env

And seeing the contents? That's my main concern now.
If so, do you have a link on how to setup that way.
Also, the way I tried only takes 3 minutes, would you trust That? It's a site for a non-profit, and can't change host.
That is also my main question would you consider that technique secure since .env isn't viewable any longer. Any other alternatives to moving Laravel up one folder, seems there should be.

bashy's avatar

@jlrdw Yes it will. I would not setup something that could allow seeing anything above Laravel public folder.

I made a sites folder at the top level and then I got the support staff to symlink it to the sites/laravel_site/public folder. So example:

/home/somesharedaccount23424/sites/laravel_site/public -> /home/somesharedaccount23424/public_html

jlrdw's avatar
Level 75

Another update I simply don't use dotenv in production. Just use the config files.

Please or to participate in this conversation.