.htaccess hardening


Hi all, just sharing a compilation of the various .htaccess security tips I gathered, some from Cloudways’ blog.

Reference for anyone who needs it. To any experts here, kindly point out any mistakes or potential problems with these rules!

# Disable directory browsing
Options All -Indexes
# Disable access to wp-config / php.ini / .htaccess files
<FilesMatch "^.*(error_log|wp-config\.php|php.ini|\.[hH][tT][aApP].*)$">
Order deny,allow
Deny from all
# Disable modifications to wp-admin / wp-includes folders
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
# Disable xmlrpc (if mobile wordpress app or pingbacks not in use to access wordpress admin)
<files xmlrpc.php>
order allow,deny
deny from all
# Prevent Script Injections
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
# END Prevent Script Injections
# Prevent Username Enumeration
RewriteCond %{QUERY_STRING} author=d
RewriteRule ^ /? [L,R=301]
# END Prevent Username Enumeration
# Restrict PHP
RewriteCond %{REQUEST_URI} !^/wp-content/plugins/file/to/exclude\.php
RewriteCond %{REQUEST_URI} !^/wp-content/plugins/directory/to/exclude/
RewriteRule wp-content/plugins/(.*\.php)$ - [R=404,L]
RewriteCond %{REQUEST_URI} !^/wp-content/themes/file/to/exclude\.php
RewriteCond %{REQUEST_URI} !^/wp-content/themes/directory/to/exclude/
RewriteRule wp-content/themes/(.*\.php)$ - [R=404,L]
# END Restrict PHP


Thanks @thienkw for compiling this. I will ask @gulshankumar and @ayaz.ahmed do share some input on this, if they can :slight_smile:


That’s great.

Hope someone can cover the following points that I’ve no expertise on.

  1. In which order should these “hardening” rules be placed in? After HTTPS redirect? After the Gzip / cache headers written by your Breeze plugin?

  2. Will these rules mess up apps / wordpress / woocommerce plugins? Especially the restrict PHP part since I’m using functions.php extensively in my theme.

Going to attempt ditching Wordfence / security plugins for faster speeds, so I hope to get expert input on this!


# Prevent Script Injections I have not tried these rules.

For rest all, I can assure that everything seems okay to me. However, few are not necessarily required.

# Disable directory browsing
It will prevent listing of your internal directory. This rule is pre-configured at Cloudways, you don’t need to repeat it. Want to give test? You may check browsing any folder yourdomain.com/wp-content/uploads/2017/

I am sure, It will not list any single files and folder on the screen.

# Disable access to wp-config / php.ini / .htaccess files
At Cloudways, I found only need of protecting php.ini for preventing directory access, rest all seems pre-configured. Generally, WordFence plugin add php.ini, as you said you are not going to use this plugin. So, you can ignore using this one. Just my opinion. As I am in more favor of less code.

# Disable modifications to wp-admin / wp-includes folders
This might be really helpful, in order to protect core files. It is recommended at Codex too.

# Disable xmlrpc (if mobile wordpress app or pingbacks not in use to access wordpress admin)

XML-RPC, you may need if you use JetPack or WordPress app. If no need, it’s a good idea to disable it to prevent brute-force attack.

# Prevent Username Enumeration
I have not tried this. Rather, I can recommend keeping strong username & Pass.

# Restrict PHP
No idea about this. Rather, I have been using a similar rule

<Files *.php>
deny from all

You may place in directory /public_html/wp-content/uploads/
Uploads directory is basically for images. We may restrict execution of PHP files inside it.



I am following Bjorn from WplearningLab for sometime now and added all the necessary codes for hardening htaccess. After that my website was working fine until I tried to create a new post. Featured image got messed up, ‘editing bar’ didn’t show when I tried to create post. Permalinks got disabled. I tried to fix but couldn’t and in the end I had to restore from backup.

PS I also used 1 or 2 codes from Cloudways blog in conjunction with Wplearninglab’s. I would be really helpful for people like me who are noobs and still want to secure their property if someone create an ‘Ultimate securing file’ and uploads it here.


I put in a page login before the login page is shown

# Protect wp-login
<Files wp-login.php>
AuthUserFile "/home/xxxxxx.cloudwaysapps.com/xxxxxxxx/private_html/.htpasswd"
AuthType Basic
AuthName "Protected area"
require valid-user