WordPress Site Security Using .htaccess Code Snippets (Subdirectory Installation)

WordPress is the most popular content management system in the world. It is being used by millions of websites on the internet. Because of this, WordPress is a highly valuable target for hackers. WordPress has built-in security features, but you can further protect your WordPress-built website by creating .htaccess files in certain directories of your WordPress installation folder and writing in them some code snippets. This tutorial is for websites that installed WordPress in a subdirectory.

Listed below are directories and directly below each of them are code snippets for .htaccess files. Browse inside your WordPress installation folder and look for the .htaccess files in the listed directories. If the .htaccess files already exist, just open them and add the corresponding lines of code to them; create the .htaccess files if they do not exist (just create a file with the name .htaccess — nothing more, nothing less). Feel free to remove any of the code snippets that you do not need from the lines of code below. Do not forget to use the actual domain name of your website instead of example.com.

Root directory

# Protect .htaccess From Unauthorized Access
<files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all
</files>


# Disable Directory Browsing
Options -Indexes


# Prevent Image Hotlinking
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?example.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ – [NC,F,L]


# temp redirect WordPress content feeds to feedburner 
<IfModule mod_rewrite.c> 
RewriteEngine on 
RewriteCond %{HTTP_USER_AGENT} !FeedBurner [NC] 
RewriteCond %{HTTP_USER_AGENT} !FeedValidator [NC] 
RewriteRule ^feed/?([_0-9a-z-]+)?/?$ http://feeds.feedburner.com/wordpressarena [R=302,NC,L]
</IfModule>


# Force “File Save As” Prompt
AddType application/octet-stream .avi .mpg .mov .pdf .xls .mp4


# Force HTTPs
RewriteEngine On
RewriteCond %{HTTP_HOST} example\.com [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R,L]

WordPress installation folder

# Disable Directory Browsing
Options -Indexes


# Protect All Vulnerable Files
<FilesMatch "^.*(error_log|wp-config\.php|php.ini|\.[hH][tT][aApP].*)$">
Order deny,allow
Deny from all
</FilesMatch>


# Disable Access to the wp-includes Folder
<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] 
</IfModule>


# Restrict Direct Access to PHP Files
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]


# Enable Browser Caching
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 2 days"
</IfModule>


# Prevent Malicious Script Injections or Block cross-site scripting (XSS)
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]


# Block Username Enumeration
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} author=d
RewriteRule ^ /? [L,R=301]


# Deny access to wp-config.php file
<files wp-config.php>
order allow,deny
deny from all
</files>


# temp redirect WordPress content feeds to feedburner 
<IfModule mod_rewrite.c> 
RewriteEngine on 
RewriteCond %{HTTP_USER_AGENT} !FeedBurner [NC] 
RewriteCond %{HTTP_USER_AGENT} !FeedValidator [NC] 
RewriteRule ^feed/?([_0-9a-z-]+)?/?$ http://feeds.feedburner.com/wordpressarena [R=302,NC,L]
</IfModule>


# Force “File Save As” Prompt
AddType application/octet-stream .avi .mpg .mov .pdf .xls .mp4


# Protects XML-RPC, prevents DDoS attack
<FilesMatch "^(xmlrpc\.php)">
Order Deny,Allow
# Allow from xx.xx.xx.xxx
# Allow from yy.yy.yy.yyy
Deny from all
</FilesMatch>

“wp-content” folder

# Disable directory browsing
Options All -Indexes

“wp-includes” folder

# Block wp-includes folder and files
<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]
</IfModule>