apache.htaccessmod-rewriteurl-rewritingfriendly-url

Page 403 Forbidden for root directory for Deny from all in .htaccess


I have next .htaccess in root directory

RewriteEngine on
RewriteRule ^$ index.php [L]
Order Deny,Allow
Deny from all
<Files index.php>
Allow from all
</Files>

And get Page 403 Forbidden for www.example.com instead of www.example.com/index.php.

URL www.example.com/index.php is available.

Access to all files in the root directory is closed. These files are generated by scripts, the file names are unknown.

How to fix it?


Solution

  • <Files index.php>
    Allow from all
    </Files>
    

    Try the following instead:

    <FilesMatch "^(index\.php)?$">
    Allow from all
    </FilesMatch>
    

    UPDATE: Added missed anchors!

    (Although I would assume you are on Apache 2.4, so you should be using the corresponding Require directives instead of Order, Deny and Allow.)

    Alternatively, replace all you existing directives with the following:

    DirectoryIndex index.php
    
    RewriteEngine On
    RewriteRule !^(index\.php)?$ - [F]
    

    This allows access to both example.com/ and example.com/index.php. To block direct access to index.php then try the following instead:

    RewriteRule ^[^/]+$ - [F]
    

    mod_dir (ie. "DirectoryIndex") is processed after mod_rewrite.


    RewriteRule ^$ index.php [L]
    

    This rule is redundant, it should be handled by DirectoryIndex instead.


    UPDATE:

    RewriteRule !^(index.php)?$ - [F] works, but I add RewriteRule !^(index2.php)?$ - [F] for second file index2.php and It dont work... I am getting 403 error for www.example.com/index2.php... I need access to several files

    By adding another rule it would end up blocking both URLs. Since one or other rule will always be successful.

    You can use regex alternation in a single rule. For example:

    RewriteRule !^(index\.php|index2\.php)?$ - [F]
    

    The same regex could be used in the <FilesMatch> container above.

    Or, if you have many such exceptions, it might be more readable to have multiple conditions. For example:

    RewriteCond %{REQUEST_URI} !=index.php
    RewriteCond %{REQUEST_URI} !=index2.php
    RewriteCond %{REQUEST_URI} !=index3.php
    RewriteRule !^$ - [F]
    

    Note, however, like your original rule, this also blocks URLs in "subdirectories", not just the root directory.