Search code examples
phpregexapache.htaccess

Why doesn't my PHP blocking .htaccess rule work?


I'm using Apache and I have this .htaccess file:

<IfModule mod_deflate.c>
        SetOutputFilter DEFLATE
        AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/x-javascript
</IfModule>

<IfModule mod_headers.c>
  <FilesMatch "\.(bin|css|dae|jpeg|jpg|JPG|json|pdf|png|PNG|rb|scss|scssc|sh|styl|svg|swf|txt|vertex|xml|zf3d|zip)$">
    Header set Access-Control-Allow-Origin *
    Header append Access-Control-Allow-Credentials true
    Header append Cache-Control "max-age=86400, public"
  </FilesMatch>
</IfModule>

## EXPIRES CACHING ##
<IfModule mod_expires.c>
        ExpiresActive On
        ExpiresByType image/jpg "access 1 year"
        ExpiresByType image/jpeg "access 1 year"
        ExpiresByType image/gif "access 1 year"
        ExpiresByType image/png "access 1 year"
        ExpiresByType text/css "access 1 year"
        ExpiresByType text/html "access 1 year"
        ExpiresByType application/pdf "access 1 year"
        ExpiresByType text/x-javascript "access 1 year"
        ExpiresByType application/x-shockwave-flash "access 1 year"
        ExpiresByType image/x-icon "access 1 year"
        ExpiresDefault "access 1 year"
</IfModule>
## EXPIRES CACHING ##

<IfModule mod_mime.c>
        AddType application/vnd.ms-fontobject eot
        AddType font/opentype otf
        AddType font/otf otf
        AddType font/truetype ttf
        AddType font/ttf ttf
        AddType application/x-font-woff woff
        AddType application/font-woff woff
</IfModule>

<IfModule mod_rewrite.c>
        Options All -Indexes
        RewriteEngine on

        # Block PHP files in data folders
        RewriteRule ^(.*)/data/.*\.(php|php3|phtml)$ / [L,R=301]
        
        # Continues...

However accessing https://example.com/data/asd/bsd/aze66atsttza5652/test.php succeeds.

Why doesn't my PHP blocking rule work?

Thanks in advance!


Solution

  • RewriteRule ^(.*)/data/.*\.(php|php3|phtml)$ / [L,R=301]
    

    Reason why your rule doesn't work because the regex pattern to match php requests is not going to work in a .htacess context. Request path in .htaccess is always relative to the path where .htaccess resides in. If it is placed in site root then resolved request path would be data/... (note, no leading /)

    You may change your rule to this to make it work from both Apache config and .htaccess:

    RewriteRule ^/?data/.+\.(php3?|phtml)$ / [L,R=301,NC]
    

    Due to presence of /? (optional /) at the start this rule will work fine from Apache config and .htaccess