6

I run several Drupal 7 installations on a dedicated server with CentOS 6.4 and Apache 2 (the package httpd-2.2.15-29.el6.centos.x86_64).

I wonder, how to properly configure the Drupal_Security_Do_Not_Remove_* handlers in my /etc/httpd/conf/httpd.conf file since .htaccess files are disabled at my server by AllowOverride None directive.

Currently I have the following sections in httpd.conf for each of my sites:

<Directory "/var/www/html">
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>
......
<VirtualHost 123.123.123.123:80>
    DocumentRoot /var/www/html/mysite1.de
    ServerName mysite1.de
    ServerAlias mysite1.de *.mysite1.de

    <IfModule mod_rewrite.c>
        <Directory "/var/www/html/mysite1.de">
            RewriteEngine on
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_URI} !=/favicon.ico
            RewriteRule ^ index.php [L]
        </Directory>
    </IfModule>
</VirtualHost>

And the recommended settings for the .htaccess are those here:

Options None
Options +FollowSymLinks

SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
<Files *>
  SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
</Files>

<IfModule mod_php5.c>
  php_flag engine off
</IfModule>

Should the result in my case be the following?

<Directory "/var/www/html">
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>
......
<VirtualHost 123.123.123.123:80>
    DocumentRoot /var/www/html/mysite1.de
    ServerName mysite1.de
    ServerAlias mysite1.de *.mysite1.de

    Options None
    Options +FollowSymLinks
    SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006
    <Files /var/www/html/mysite1.de/sites/default/files/*>
        SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003
    </Files>

    <IfModule mod_rewrite.c>
        <Directory "/var/www/html/mysite1.de">
            RewriteEngine on
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_URI} !=/favicon.ico
            RewriteRule ^ index.php [L]
        </Directory>

        <Directory "/var/www/html/mysite1.de/sites/default/files">
            php_flag engine off
        </Directory>
    </IfModule>
</VirtualHost>
  • 2
    @JhilkeDai he didn't post the full httpd.conf so just because we can't see it doesn't mean it's not there. – Beebee Nov 21 '13 at 10:36
  • 3
    @JhilkeDai The question explicitly says ".htaccess files are disabled at my server by AllowOverride None directive." I'm not sure how that even relates to this question, though – Clive Nov 21 '13 at 10:47
  • 1
    @JhilkeDai Sure, but AllowOverride has no bearing on this question...which is essentially, "If I put this Drupal directive here, am I still plugging the security hole that it was introduced to stop, bearing in mind AllowOverride is set to None?" – Clive Nov 21 '13 at 10:51
  • 2
    @JhilkeDai Sorry I don't understand. This question has very little, if anything, to with .htaccess files, & everything to do with the vhost config. If there's an AllowOverride None directive, which the OP asserts that there is, then any directives in .htaccess are moot; completely un-used. I'm not sure why you'd assume there are further directives on specific subfolders of the site, when the OP hasn't mentioned it. I'm sure you're just trying to second-guess other potential issues and provide helpful solutions to those, but it might be better to address what's in the question :) – Clive Nov 21 '13 at 11:29
  • 1
    I've updated the excerpt with the .htaccess part - for JhilkeDai - eventhough it doesn't really matter here. Yes, I'd like to know, if I have plugged the Drupal security holes properly by my httpd.conf. – Alexander Farber Nov 21 '13 at 12:48
5

.htaccess files are just convienance mechanisms to change Apache configuration without needing to restart Apache (.htaccess are scanned/run any request) -- for performance reasons you may want to place any directives in .htaccess files directly into a vhost entry so the configuration is loaded and stored only one time; on Apache startup.

From the security notice SA-2013-003:

Warning: Fixing the code execution prevention may require server configuration; please read:

To fix the code execution prevention vulnerability on existing Apache installations also requires changes to your site's .htaccess files in the files directories. Until you do this, your site's status report page at admin/reports/status will display error messages about the problem. Please note that if you are using a different web server such as Nginx the .htaccess files have no effect and you need to configure PHP execution protection yourself in the respective server configuration files.

To fix this issue, you must edit or replace the old .htaccess files manually. Copies of the .htaccess files are found in the public files directory and temporary files directory, and (for Drupal 7 only) the private files directory if your site is configured to use one.

So you take whatever is in the .htaccess file in your websites configured files directories (public, private, etc) and assure those same rules are in the vhost entry for the same set of directories. Typically you do this with a <Directory> directive:

<Directory "/var/www/html">
    Options Indexes FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>
......
<VirtualHost 123.123.123.123:80>
    DocumentRoot /var/www/html/mysite1.de
    ServerName mysite1.de
    ServerAlias mysite1.de *.mysite1.de

    <IfModule mod_rewrite.c>
        <Directory "/var/www/html/mysite1.de">
            RewriteEngine on
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_URI} !=/favicon.ico
            RewriteRule ^ index.php [L]
        </Directory>
    </IfModule>

    # Enforce new security rules from SA-CORE-2013-003.
    # repeat this block as needed per known "files" directories.
    <Directory "/var/www/html/mysite1.de/sites/default/files">
      # Turn off all options we don't need.
      Options None
      Options +FollowSymLinks

      # 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_php5.c>
        php_flag engine off
      </IfModule>
    </Directory>
</VirtualHost>

It doesnt matter if the default web directory has AllowOverride None; typically another conf file included down the apache startup chain, or the virtual host loading setup (such as the following in Ubuntu) can be tweaked to allow any combination of Overrides:

# Ubuntu apache2.conf last line ...
# Include the virtual host configurations:
Include sites-enabled/

This is just saying include *.conf from sites-enabled these dont have to be vhost entries they can be any files with apache directives (but its cleanest to have them be vhost entries) and apache loads the configuration files following a filename pattern/sort.

  • Bah, all this work for a security hole. Everyone should just move to nginx, it's so much better ;) Good explanation, I think we have out canonical question and answer for this topic now – Clive Nov 21 '13 at 16:11
  • 1
    @Clive I'm proxying Nginx to a backend Apache with minor headaches ... but I do like the conf file syntax better :D – tenken Nov 21 '13 at 16:15
  • So both Drupal_Security_Do_Not_Remove_See_SA_* handlers should be only called inside the sites/default/files dir? – Alexander Farber Nov 22 '13 at 9:23
  • 1
    @AlexanderFarber Have a read of the docs, they explain it very clearly – Clive Nov 22 '13 at 15:22
  • 1
    This answer is solid. One extra tip is to "try it and see." This protection is meant to stop the execution of a php script if something (module, other code) happens to let that get uploaded. So, to test that it works just upload your own php file (e.g. via sftp or ssh) and see if it gets executed. If it doesn't then things are working right. – greggles Nov 28 '13 at 17:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.