15 Useful .htaccess Snippets for Your WordPress Site

Having a well-configured .htaccess file is crucial if you want to increase security and reduce vulnerabilities on your WordPress site. Usually, the main goal of creating a custom .htaccess file is to prevent your site from being hacked but it’s also an excellent way to handle redirects and manage cache-related tasks.

.htaccess is a configuration file used on Apache web servers. Most WordPress sites run on an Apache server, although a small portion is powered by Nginx. In this article, you can find a collection of .htaccess code snippets, most of which you can use to secure your website while the rest implements other useful features.

Don’t forget to back up the .htaccess file before you edit it so that you can always return to the previous version if something goes wrong.

And, if you’re someone who rather not touch configuration files I recommend you the BulletProof Security plugin which is the most reliable (and probably the oldest) free .htaccess security plugin on the market.

Create the default WP .htaccess

.htaccess works on a per-directory basis which means that each directory can have its own .htaccess file. It can easily happen that your WordPress site doesn’t have a .htaccess file yet. If you don’t find a .htaccess file in your root directory create an empty text file and name it to .htaccess.

Below, you can find the default .htaccess WordPress uses. Whenever you need this code you can quickly look it up in the WordPress Codex. Note that there is a different .htaccess for WP Multisite.

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress

The lines beginning with # are comments. Don’t edit anything between the lines # BEGIN WordPress and # END WordPress. Add your custom .htaccess rules below these default rules.

All code snippets you can find in this article go to the core .htaccess file found in your root directory.

1. Deny access to all .htaccess files

The code below denies access to all .htaccess files you have installed in your WordPress. This way you can prevent people from seeing your web server configurations.

# Denies access to all .htaccess files
<Files ~ "^.*\.([Hh][Tt][Aa])">
Order Allow,Deny
Deny from all
Satisfy all

2. Protect your WP configuration

The wp-config.php file contains all your WP configurations, including your database login and password. You can either deny it from everyone or give permission to admins to access it.

If you choose the latter comment out the # Allow from xx.xx.xx.xxx line (remove # from the beginning of the line) and insert the admin’s IP address in place of xx.xx.xx.xxx.

# Protects wp-config
<Files wp-config.php>
Order Allow,Deny
# Allow from xx.xx.xx.xxx
# Allow from yy.yy.yy.yyy
Deny from all

3. Prevent XML-RPC DDoS attack

WordPress supports XML-RPC by default, which is an interface that makes remote publishing possible. However, while it’s a great feature, it’s also one of WP’s biggest security vulnerability as hackers may exploit it for DDoS attacks.

If you don’t want to use this feature it’s better to just disable it. Just like before, you can add exceptions by commenting out the # Allow from xx.xx.xx.xxx line and adding the IPs of your admin(s).

# 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

4. Protect your admin area

It’s also a good idea to protect the admin area by giving access only to administrators. Here, don’t forget to add at least one “Allow” exception otherwise you won’t be able to access your admin at all.

# Protects admin area by IP
AuthUserFile /dev/null
AuthGroupFile /dev/null
AuthName "WordPress Admin Access Control"
AuthType Basic
Order Deny,Allow
Deny from all
Allow from xx.xx.xx.xxx
Allow from yy.yy.yy.yyy

5. Prevent directory listing

Most WordPress sites don’t disable directory listing, which means anyone can browse their folders and files, including media uploads and plugin files. It’s needless to say that this is a huge security vulnerability.

Below, you can see how a typical WordPress directory listing looks like.

Directory listing

Luckily, you just need one line of code to block this feature. This code snippet will return a 403 error message to anyone who wants to access your directories.

# Prevents directory listing
Options -Indexes

6. Prevent username enumeration

If WP permalinks are enabled, it’s quite easy to enumerate usernames using the author archives. The revealed usernames (including the admin’s username) then can be used in brute force attacks.

Insert the code below into your .htaccess file to prevent username enumeration.

# Prevents username  enumeration
RewriteCond %{QUERY_STRING} author=d
RewriteRule ^ /? [L,R=301]

7. Block spammers and bots

Sometimes you may want to restrict access from certain IP addresses. This code snippet provides an easy way to block spammers and bots you already know.

# Blocks spammers and bots
<Limit GET POST>
Order Allow,Deny
Deny from xx.xx.xx.xxx
Deny from yy.yy.yy.yyy
Allow from all

8. Prevent image hotlinking

Although not a security threat, image hotlinking is still an annoying thing. People don’t only use your images without your permission but they even do it at your cost. With these few lines of code, you can protect your site from image hotlinking.

# Prevents image hotlinking
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourwebsite.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourwebsite2.com [NC]
RewriteRule \.(jpe?g?|png|gif|ico|pdf|flv|swf|gz)$ - [NC,F,L]

9. Restrict direct access to plugin & theme PHP files

It can be dangerous if someone directly calls your plugin and theme files, whether it happens accidentally or by a malicious attacker. This code snippet comes from the Acunetix website security company; you can read more about this vulnerability in their blog post.

# Restricts access to PHP files from plugin and theme directories
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]

10. Set up permanent redirects

You can easily handle permanent redirects with .htaccess. First you have to add the old URL, then follow the new URL that points to the page you want to redirect the user to.

# Permanent redirects
Redirect 301 /oldurl1/ http://yoursite.com/newurl1
Redirect 301 /oldurl2/ http://yoursite.com/newurl2

11. Send visitors to a maintenance page

We wrote about this technique in detail here. You need a separate maintenance page (maintenance.html in the example) for this .htaccess rule to work. This code puts your WordPress site into maintenance mode.

# Redirects to maintenance page
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^123\.456\.789\.000
RewriteCond %{REQUEST_URI} !/maintenance.html$ [NC]
RewriteCond %{REQUEST_URI} !\.(jpe?g?|png|gif) [NC]
RewriteRule .* /maintenance.html [R=503,L]

12. Restrict all access to WP includes

The /wp-includes/ folder contains the core WordPress files that are necessary for the CMS to work. There are no content, plugins, themes or anything else a user may want to access here. So to harden security it’s best to restrict all access to it.

# Blocks all wp-includes folders 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]

13. Block cross-site scripting (XSS)

The following code snippet is from WP Mix and it protects your site against some common XSS attacks, namely script injections and attempts to modify global and request variables.

# Blocks some XSS attacks
<IfModule mod_rewrite.c>
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]

14. Enable browser caching

As I mentioned before, .htaccess is not only good for security reasons and redirections but it can also help you manage the cache. The code snippet below is from Elegant Themes and it makes browser caching possible by enabling visitors to save certain kinds of files, so next time they visit they don’t have to download them again.

# Enables 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"

15. Set up custom error pages

You can use .htaccess to set up custom error pages on your WordPress site. For this method to work, you also need to create the custom error pages (custom-403.html, custom-404.html in the example) and upload them to your root folder.

You can set up a custom error page for any HTTP error status code (4XX and 5XX status codes) you want.

# Sets up custom error pages
ErrorDocument 403 /custom-403.html
ErrorDocument 404 /custom-404.html