Securing Drupal file directories
Drupal uses three directories for files. They are the 'public', 'private' and 'temporary' directories. On install these will be configured to be secure.
Each file directory must be protected against remote code execution with a .htaccess file. By default, Drupal will do this automatically, by trying to create a .htaccess file inside the directory. That file provides the protection for Apache web servers.
Check for insecure directories
Navigate to Reports -> Status report.
Any insecure directories are reported in the 'Errors found' section:
Private files directory: Not fully protected
See https://www.drupal.org/SA-CORE-2013-003 for information about the recommended .htaccess file which should be added to the private:// directory to help protect against arbitrary code execution.
.htaccess file, in which case you will probably also see something like this:File system: Writable (public download method)
The directory /var/www/example.org/public_html/web/../private is not writable. You may need to set the correct directory at the file system settings page or change the current directory's permissions so that it is writable.
Add .htaccess to an insecure directory
Find the appropriate path
Navigate to Configuration -> Media -> File system
Search for "Public file system path", "Private file system path" and "Temporary directory". These will tell you where to find the public, private and temporary file directories.
Ensure .htaccess exists
.htaccess file. If the directory does not have a .htaccess file, then one must be added. This can be done by navigating to Reports -> Status, and refreshing the page..htaccess file should be created automatically by the FileSecurity function, if Drupal can write into the folder. If necessary, alter the permissions, refresh the Status page, and as soon as the .htaccess file is created, the warnings should disappear, and you can verify its existence.If not, the file can be created manually using the contents shown below for the default .htaccess file (public and temporary directories) or the private directory .htaccess file.
Default .htaccess file
If the directory does have a .htaccess file, it may be outdated or otherwise not configured correctly. In this case, ensure the file has the contents shown below for the default .htaccess file (for public and temporary directories).
# Turn off all options we don't need.
Options -Indexes -ExecCGI -Includes -MultiViews
# Set the catch-all handler to prevent scripts from being executed.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
# Override the handler again if we're run later in the evaluation list.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>
# If we know how to do it safely, disable the PHP engine entirely.
<IfModule mod_php.c>
php_flag engine off
</IfModule>Private directory .htaccess file
The private directory should not be served by Apache, and access from the outside should be denied, by adding a few extra lines at the top of the .htaccess:
# Deny all requests from Apache 2.4+.
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
# Deny all requests from Apache 2.0-2.2.
<IfModule !mod_authz_core.c>
Deny from all
</IfModule>
# Turn off all options we don't need.
Options -Indexes -ExecCGI -Includes -MultiViews
# Set the catch-all handler to prevent scripts from being executed.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
# Override the handler again if we're run later in the evaluation list.
SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>
# If we know how to do it safely, disable the PHP engine entirely.
<IfModule mod_php.c>
php_flag engine off
</IfModule>Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion