.htaccess security best practices in Apache 2.4.6+

Date posted: 2018-11-05
Last updated: 2026-05-10

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. Apache Access Controle done right in WordPress .htaccess.



As with everything new, older documentation and random blog posts are never updated. They still show you how to old methods or syntax, potentially leaving you with unprotected websites. Not what you had in mind, now is it?… Here is Apache Access Control done right in .htaccess, Use this to secure your web applications like WordPress, Drupal and Joomla.

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.

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

Securing web applications with .htaccess files the wrong way

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

<Files wp-config.php>
  Order Allow,Deny
  Deny from all
</Files>

Joomla configuration.php:

<Files configuration.php>
  Order Allow,Deny
  Deny from all
</Files>

Drupal settings.php:

<Files settings.php>
  Order Allow,Deny
  Deny from all
</Files>

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: https://httpd.apache.org/docs/2.4/mod/mod_access_compat.html.

Access authorization in Apache 2.4.6 – Properly secure websites using .htaccess and mod_authz_host

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 198.51.100.15
</Files>

# Protect configuration.php
<Files configuration.php>
	Require all denied
	# substitute with your IP address
	Require ip 198.51.100.15
</Files>

# Protect settings.php
<Files settings.php>
	Require all denied
	# substitute with your IP address
	Require ip 198.51.100.15
</Files>

You get the idea with the different configuration files for WordPress, Drupal and Joomla. Use wp-config.php, settings.php or configuration.php. For the rest of the article, I focus on WordPress wp-config.php, substitute this with the file(s) you use.

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 198.51.100.15
	</IfModule>

	# Apache 2.4
	<IfModule mod_authz_core.c>
		Require all denied
		Require ip 198.51.100.15
	</IfModule>
</Files>

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

Found this guide helpful? You can support my independent deep dives into Windows Server and DevOps by donating via PayPal. Every bit of support helps keep saotn.org fast and updated!

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 203.0.113.0/24

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

<RequireAll>
	Require all granted
	Require not ip 203.0.113.0/24
</RequireAll>

This blocks an entire /24 subnet, consisting of 256 IP addresses. If you want to block one IP address, use:

<RequireAll>
	Require all granted
	Require not ip 203.0.113.12
</RequireAll>

You can expand this with single IP addresses until you find blocking a subnet viable:

<RequireAll>
	Require all granted
	Require not ip 203.0.113.12
	Require not ip 203.0.113.14
</RequireAll>
<RequireAll>
	Require all granted
	Require not ip 203.0.113.12
	Require not ip 203.0.113.14
	Require not ip 203.0.113.15
	Require not ip 203.0.113.192
</RequireAll>

Neat, right?! 🙂

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>

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]

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 keeping your sites more secure! 🙂

Secure WordPress wp-login.php with an IP whitelist

Use your website’s .htaccess file to secure access to your wp-login.php file by creating an IP whitelist.

Whitelist? Blacklist?
Clarification: a whitelist only includes the addresses of those who have been granted access. The opposite is a blacklist: everyone has access unless they are included on the blacklist. Because a blacklist grants access to everyone by default (unless…), this is a less secure option.

These days, a whitelist often refers to a allowlist. This is more inclusive…

The following example blocks access to /wp-login.php but allows only a few IP addresses:

# Block access to wp-login.php for not listed IPs
# wp-login.php whitelist
<Files wp-login.php>
	Require ip 203.0.113.15
</Files>

In this example, only IP address 203.0.113.15 is granted access.

You can also allow multiple IP addresses or whole IP networks / netblocks:

# Multiple IP addresses whitelisted
<Files wp-login.php>
	Require ip 203.0.113.15 203.0.113.16 203.0.113.17

	# Or entire networks / IP blocks
	Require ip 203.0.113.0/255.255.255.0
</Files>

Conclusion .htaccess best practices for web applications

In this post you learned different Apache webserver versions have different options to block (or allow) IP addresses on your website. Unfortunately newer syntaxis and modules don’t work with older Apache versions. Therefore it is important to know which version you are on (if you are on an older Apache version, ask your hosting provider for an upgrade!), so you are able to use the appropriate functions to secure your web application properly.

Key Takeaways

  • Older documentation often leads to insecure websites, so use updated syntax for Apache .htaccess files.
  • For Apache 2.4.6 and higher, use mod_authz_core instead of deprecated directives for access control.
  • To secure WordPress, Drupal, and Joomla, use the new syntax with .htaccess to allow or block IP addresses effectively.
  • Implement IP whitelisting for wp-login.php to restrict access and improve security.
  • Always verify your Apache version to utilize the best security practices for WordPress .htaccess security.

Did you like this post?

Your generosity helps pay for the ongoing costs associated with running this website like coffee, hosting services, library mirrors, domain renewals, time for article research, and coffee, just to name a few. ❤️

Rate this post!

2 thoughts on “.htaccess security best practices in Apache 2.4.6+”

Leave a Comment


Share via
Copy link