How do you ensure that .htaccess follows custom 403 redirects?

Viewed 85

I am running a LAMP Server on Linux. In apache2.conf we have:

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all granted
    <LimitExcept GET POST HEAD>
    deny from all
    </LimitExcept>
        ErrorDocument 403 /var/www/html/error.html
        RewriteEngine On
        RewriteCond %{REQUEST_METHOD} POST
        RewriteCond %{REMOTE_ADDR} !127.0.0.1 
        RewriteRule .* - [F]
</Directory>

<Directory /var/www/>
    Options FollowSymLinks
    AllowOverride None
    Require all granted
    <LimitExcept GET POST HEAD>
    deny from all
    </LimitExcept>
    ErrorDocument 403 /var/www/html/error.html
        RewriteEngine On
        RewriteCond %{REQUEST_METHOD} POST
        RewriteCond %{REMOTE_ADDR} !127.0.0.1 
        RewriteRule .* - [F]
        RewriteCond %{HTTP_USER_AGENT} ^-?$ [OR]
        RewriteCond %{HTTP_USER_AGENT} python-requests/2.18.4 [NC,OR]
        RewriteCond %{HTTP_USER_AGENT} curl/7.47.0 [NC]
        RewriteRule .* - [F,L]
</Directory>

<Directory /var/www/html>
    Options FollowSymLinks
    AllowOverride None
    Require all granted
    <LimitExcept GET POST HEAD>
    deny from all
    </LimitExcept>
        ErrorDocument 403 /var/www/html/error.html
        RewriteEngine On
        RewriteCond %{REQUEST_METHOD} POST
        RewriteCond %{REMOTE_ADDR} !127.0.0.1 
        RewriteRule .* - [F]
        RewriteCond %{HTTP_USER_AGENT} ^-?$ [OR]
        RewriteCond %{HTTP_USER_AGENT} python-requests/2.18.4 [NC,OR]
        RewriteCond %{HTTP_USER_AGENT} curl/7.47.0 [NC]
        RewriteRule .* - [F,L]
</Directory>

<Directory /var/www/html/wiki>
    Options FollowSymLinks
        AllowOverride All
        Require all granted
        <LimitExcept GET POST HEAD>
        deny from all 
        </LimitExcept>
        ErrorDocument 403 /var/www/html/error.html
        RewriteEngine On
        RewriteCond %{REQUEST_METHOD} POST
        RewriteCond %{REMOTE_ADDR} !127.0.0.1 
        RewriteRule .* - [F]
    RewriteCond %{HTTP_USER_AGENT} ^-?$ [OR]
    RewriteCond %{HTTP_USER_AGENT} python-requests/2.18.4 [NC,OR]
        RewriteCond %{HTTP_USER_AGENT} curl/7.47.0 [NC]
        RewriteRule .* - [F,L]
</Directory>

Note the ErrorDocument command is identical in each and every directory block specified in apache2.conf including In the .htaccess file in that directory and in the .htaccess files in all of the sub directories under it (which are carbon copies of the same .htaccess file), we have, in relevant part:

<IfModule mod_authz_core.c>
    Require all denied
    ErrorDocument 403 /var/www/html/error.html
</IfModule>
<IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
    ErrorDocument 403 /var/www/html/error.html
</IfModule>
ErrorDocument 403 /var/www/html/error.html

The problem is that on testing, we get a 403 as expected, BUT the page displayed is the generic 403 page plus a line displaying "Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request."

My understanding is that "Deny from all" should give the 403 redirect to the designated ErrorDocument given that the following is also in every directory block in apache2.conf:

ErrorDocument 403 /var/www/html/error.html

So why is error.html getting an additional duplicative 403 redirect? This doesn't seem to make sense.

1 Answers
ErrorDocument 403 /var/www/html/error.html

The ErrorDocument directive takes a document root relative URL-path as the second argument for the error document, not an absolute file-path as you appear to be using here.

The DocumentRoot does not appear to be defined in the config you've posted. However, from your file-path, I would expect this to be set to /var/www/html. In which case the ErrorDocument should be defined as follows:

ErrorDocument 403 /error.html

You do not need to repeat the ErrorDocument everywhere if it's the same.


Aside: A few additional notes...

  1. mod_rewrite directives do not inherit by default, so the mod_rewrite directives in lower directories completely override the mod_rewrite directives in the parent directories.

  2. You should not be allowing access to the root of the filesystem. ie. <Directory />

  3. You are mixing Apache 2.4 (Require all granted) and Apache 2.2 (deny from all) authorisation directives. You should not mix the two in the same context. The Apache 2.2 directives are formerly deprecated on Apache 2.4 and will take priority over the Apache 2.4 directives.

Related