You are here: » WordPress » WordPress .htaccess security best practices in Apache 2.4.6+

WordPress .htaccess security best practices in Apache 2.4.6+


Apache Access Control done right in WordPress .htaccess, ‘Allow/Deny from all’ versus ‘Require All Granted/Denied’

Since Apache 2.4.6, a new module is used to configure and set up access control for websites: mod_authz_core. This means you have to use a different syntax for allowing or blocking hosts and IP addresses to your website. But unfortunately, old documentation is never updated and people even still write blog posts using that old syntax, leaving you with an unprotected website. Not what you had in mind, now is it?…

Securing WordPress with .htaccess files the wrong way

I see it all to often: blog posts telling you to secure WordPress using the following snippet in a .htaccess file, securing wp-config.php:

<Files wp-config.php> Order Allow,Deny Deny from all </Files>
Code language: Apache (apache)

This is wrong! Wrong! Wrong!

Unfortunately this does not work with Apache 2.4.6 and higher! Apache may provide the following error in your errorlog:

Invalid command ‘deny’, perhaps misspelled or defined by a module not included in the server configuration

I find it hard to believe so called “WordPress Security” companies still write posts explaining the old, non-functional, syntax without even mentioning the new, correct syntax…

Satisfy, Order, Deny and Allow have all been deprecated and replaced with new Require directives.

Yes, there is Apache’s mod_access_compat, that provides compatibility for old directives like Order, Allow, Deny and Satisfy. But depending on such a module is not recommended, since it’s deprecated by mod_authz_host:

Access authorization in Apache 2.4.6 – Properly secure WordPress

Psst, here are 7 snippets to use .htaccess as a Web Application Firewall. However, .htaccess files should not be used for security restrictions.

So now, for once and for all: here is how to use the new Apache 2.4.6+ mod_authz_host syntax in your WordPress .htaccess files:

# Protect wp-config.php <Files wp-config.php> Require all denied # substitute with your IP address Require ip </Files>
Code language: Apache (apache)

For compatibility with older Apache versions, you can wrap this up in a condition:

<Files wp-config.php> # Apache 2.2 <IfModule !mod_authz_core.c> Order Deny,Allow Deny from all Allow from </IfModule> # Apache 2.4 <IfModule mod_authz_core.c> Require all denied Require ip </IfModule> </Files>
Code language: Apache (apache)

Note: by using .htaccess files you leave Nginx and IIS web servers unprotected! You can use .htaccess in IIS though, but don’t rely on just .htaccess files for your website defense.

Block IP addresses in .htaccess

This is not just for WordPress, but for all websites hosted on Apache (Drupal, Joomla, …). Another change is the syntax to block an IP address in .htaccess. Where you used to use the following:

Order Allow,Deny Allow from all Deny from
Code language: Apache (apache)

Don’t use this above .htaccess code! You now have to use mod_authz_core syntax again:

<RequireAny> Require all granted Require not ip </RequireAny>
Code language: Apache (apache)

Deny all requests for *.php

For example, to deny all requests for *.php files you can use:

<Files *.php> # Apache 2.2 <IfModule !mod_authz_core.c> Order Deny,Allow Deny from all </IfModule> # Apache 2.4 and up <IfModule mod_authz_core.c> Require all denied </IfModule> </Files>
Code language: Apache (apache)

You can use this to block PHP execution in wp-conten/uploads for example.

Block access to WordPress’ debug.log file

It is important to block access to WordPress’ debug.log file in wp-content/. Or all log files for that matter, as they contain important information about your website and possibly even passwords.

Use mod_rewrite to simply block requests to *.log:

RewriteEngine On RewriteRule \Q.log\E - [F,L,NC]
Code language: Apache (apache)

Here, \Q and \E are used to remove the special meaning from a sequence of characters.

If you want to remove the special meaning from a sequence of characters, you can do so by putting them between \Q and \E. The \Q…\E sequence is recognized both inside and outside character classes.

Regular expression syntax

But as with the example above, you could also use a <Files "debug.log"> ... </Files> block in your .htaccess file. I just wanted to show you more than one way.

Hope this helps! :)

Leave a Reply

Your email address will not be published. Required fields are marked *