Search code examples
phplaravel.htaccesscyber-panel

Protect .env, .yalm, .json files for Laravel 8 Project Installed on cyberPanel VPS


I have cyberPanel installed on my VPS server. The .htaccess file is working fine in the local system. But when I moved the Laravel 8 Project to my VPS server the .htaccess file did not work fully. I want to protect .env, .yalm, .json, and other files from direct access using the URL.

Here is my .htaccess file

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>
    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Send Requests To Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>
<Files .env>
    order allow,deny
    Deny from all
</Files>
<Files *.json>
    order allow,deny
    Deny from all
</Files>
<Files *.lock>
    order allow,deny
    Deny from all
</Files>
<Files *.xml>
    order allow,deny
    Deny from all
</Files>
<Files *.yml>
    order allow,deny
    Deny from all
</Files>

Solution

  • With the limited information given there is no obvious reason why these files are not blocked. However, if the mod_rewrite directives are working "fine" (as suggested in comments) then you could use mod_rewrite to block these requests instead.

    For example, immediately after the RewriteEngine On directive try the following instead:

    # Block access to certain file types
    RewriteRule \.(env|json|lock|xml|yml)$ - [F]
    

    The above would serve a 403 Forbidden for any URL that ends in one of the stated extensions (or simply the file .env). This is regardless of whether the underlying file exists or not (unlike the <Files> directive).

    HOWEVER, if your site is behind a front-end proxy that serves your static content then this won't work either as any direct request for a physical file bypasses your application server and the above rule is never processed.


    UPDATE:

    Aside:

    <Files .env>
        order allow,deny
        Deny from all
    </Files>
    <Files *.json>
        order allow,deny
        Deny from all
    </Files>
    <Files *.lock>
        order allow,deny
        Deny from all
    </Files>
    <Files *.xml>
        order allow,deny
        Deny from all
    </Files>
    <Files *.yml>
        order allow,deny
        Deny from all
    </Files>
    

    You've not stated what version of Apache you are on, or if indeed you are running LiteSpeed instead - as I queried in comments below your question.

    If on Apache 2.4 then Order and Deny directives are formerly deprecated and have been moved to an optional extension (mod_access_compact) - this is not installed by default. However, in the absence of any error I assume this is not the case? LiteSpeed has a tendency to suppress any errors (although the error log should still contain these) - which makes debugging that much harder.

    On Apache 2.4 you should be using the corresponding Require directive instead.

    However, there is also a lot of unnecessary repetition here. I would instead combine these <Files> containers into a single <FilesMatch> container and use a regex instead. For example, the above would be the same as the following on Apache 2.4:

    <FilesMatch "\.(env|json|lock|xml|yml)$">
        Require all denied
    </FilesMatch>
    

    (Having said that, LiteSpeed tends to behave more like Apache 2.2 so you should probably stick with the Order and Deny directives if using LiteSpeed.)

    You should always have "blocking" directives at the top of the config file. (Although moving the <Files> containers to the top will not make any difference in this case.)