Search code examples
phpwordpressapache.htaccessmamp

MAMP .htaccess LimitExcept doesn't block GET request


I'm learning Apache directives in .htaccess and testing security settings. I found out about the LimitExcept directive.

I have a wordpress directory in localhost and an .htaccess inside so the directives impact all subdirectories like my project files.

Here is my code in .htaccess:

Options All -Indexes
FileEtag None

<files wp-config.php>
order allow,deny
deny from all
</files>

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{QUERY_STRING} ^author=([0-9]*)
RewriteRule .* - [F]
</IfModule>

<LimitExcept POST HEAD>
Order Deny,Allow
Deny from all
</LimitExcept>

#<IfModule mod_rewrite.c>
#RewriteEngine on
#RewriteCond %{REQUEST_METHOD} ^GET
#RewriteRule .* - [R=400]
#</IfModule>

What troubles me is that the LimitExcept directive I use does not block me from my homepage. It is like the GET request is allowed.

I have to add or use in place the Rewrite directives to block my GET request.

I also found out that if I left the HEAD method out from the current LimitExcept directive, then requesting my homepage will correctly return a Forbidden request response.

I understand that other settings can be applied at the server config but I don't want to change at that level as I may not have access to this config from my shared hosting service server.

So do I miss something or there is something wrong with the LimitExcept directive ?


Solution

  • <LimitExcept POST HEAD>
    Order Deny,Allow
    Deny from all
    </LimitExcept>
    

    It seems that HEAD and GET are intrinsically linked. Block one and you block the other. From the docs for <limit> (which also covers <LimitExcept>):

    If GET is used, it will also restrict HEAD requests.

    In my tests, the opposite is also true... if you restrict HEAD then GET is also restricted.

    So, back to your <LimitExcept POST HEAD> directive... by creating an exception for HEAD, it would seem you are also creating an exception for GET. You need to remove HEAD from the directive. (Assuming you are on Apache 2.4, you should also be using the Require directive, rather than the older Order / Deny directives.) For example:

    <LimitExcept POST>
    Require all denied
    </LimitExcept>