Previously, all .php files anywhere in the document root were publicly executable on the web (using the Apache webserver)
Starting with Drupal 8, the .htaccess
file in the document root denies access to all .php files that are located in nested subdirectories.
Drupal 7
A PHP script placed into e.g. ./sites/all/modules/js/js.php
could be accessed and executed over the web.
Drupal 8
By default, access is only granted to PHP front controller scripts of Drupal core in the document root (/*.php
) and the core directory (/core/*.php
).
To enable public access to a custom PHP script in e.g. ./modules/js/js.php
, the .htaccess
file in Drupal's root directory needs to be adjusted accordingly. Example:
# For security reasons, deny access to other PHP files on public sites.
# Note: The following URI conditions are not anchored at the start (^),
# because Drupal may be located in a subdirectory. To further improve
# security, you can replace '!/' with '!^/'.
# Allow access to PHP files in /core (like authorize.php or install.php):
RewriteCond %{REQUEST_URI} !/core/[^/]*\.php$
# Allow access to test-specific PHP files:
RewriteCond %{REQUEST_URI} !/core/modules/system/tests/https?.php
# Allow access to Statistics module's custom front controller.
# Copy and adapt this rule to directly execute PHP files in contributed or
# custom modules or to run another PHP application in the same directory.
RewriteCond %{REQUEST_URI} !/core/modules/statistics/statistics.php$
# Also allow access to a custom PHP script
RewriteCond %{REQUEST_URI} !/path/from/docroot/to/custom/script.php$
# Deny access to any other PHP files that do not match the rules above.
# Specifically, disallow autoload.php from being served directly.
RewriteRule "^(.+/.*|autoload)\.php($|/)" - [F]
Except from the # Also allow access to a custom PHP script
part, the rest is copied from core .htaccess
. There is a FilesMatch
section on top but that only denies paths like .php.bak
or .php.orig
.