Search code examples
apache.htaccessmod-rewrite

Block access to all .php files except some specific files (htaccess)


I want to send visitor to custom 404 error page when it tries to access to a .php URL, but with some specific exceptions:

Exceptions like:

(maybe-something/)/allowed-file.php

My current .htaccess file blocks access to all .php files:

ErrorDocument 404 /error404.php
ErrorDocument 403 /error404.php
Options -MultiViews

RewriteEngine on
RewriteCond %{SERVER_PORT} 80

# Force WWW & SSL
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

##.php envia a 404
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.+)\.php - [F,L]

How can I add a few dozen of specific exceptions?


Solution

  • ##.php envia a 404
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^(.+)\.php - [F,L]
    

    Change this to:

    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteCond %{REQUEST_URI} !/allowed-file\.php$
    RewriteRule .\.php - [F]
    

    The ! prefix negates the expression. So the 2nd condition is successful when the requested URL is not /allowed-file.php or /<anything>/allowed-file.php. The 2nd argument to the RewriteCond directive (following the ! prefix) is a regular expression (by default).

    To add more exceptions; add more conditions (RewriteCond directives).

    Note that I removed the capturing group in the RewriteRule pattern since this is not being used. And the L flag is not required when using the F flag (it is implied).

    However, this rule is in the wrong place in your config file. It should be immediately after the RewriteEngine directive and before the canonical redirects.

    Also, that stray RewriteCond %{SERVER_PORT} 80 directive (immediately after the RewriteEngine directive) is superfluous and should be removed (to avoid accidental errors later).

    Reference: