Andreas Hecht January 16th, 2015

No Trespassing! Eight Essential .htaccess Tricks for WordPress

The .htaccess file is a powerful configuration tool for web servers or web hosting packages that should always be used when you host WordPress yourself. The file can be found in the root directory of a WordPress installation (where the folders wp-content, wp-admin, etc. are located). In this article, we will explain the basic file settings for a safer and better WordPress besides the tweakage of its own configuration files. barbed-wire-438185_640 Image by Mac Kenzie from Pixabay

Preparing the .htaccess

First of all, locate the file. The following screenshot shows its location. htaccess It’s very important to back up the .htaccess before you make any changes. Just copy the file into a new/different folder. A Mac OS X characteristic: Mac considers all files with a leading period in their name as system files, including .htaccess. If you drag and drop such a file to the desk, it'll be hidden. You can use the small dashboard widget Hidden Files to show and hide hidden files. The widget works fine with Yosemite as well as older iterations. Refresh your browser after every single modification to the .htaccess to make sure your website still works. .htaccess files are very delicate. Just one wrong parameter can crash your online presence. If this happens to you, upload the backup file. Usually, this should solve the problem.

Let Them Code Snippets Begin

Add the following code snippets to the end of the .htaccess file.

1. Deny Access to .htaccess from Outside

In order to protect the important server control file .htaccess from outside attacks, we'll restrict access to (S)FTP.
1
2
3
4
5
# Deny access to .htaccess and .htpasswd if in use
<FilesMatch "(.htaccess)">
  Order deny,allow
  Deny from all
</FilesMatch>

2. Prevent Image Hotlinking

The so-called hotlinking of images can become a real problem. Hotlinking means that people don’t even bother to download the images from your website to link them from their own space afterwards. Instead, hey just specify the path to your image and call them from your site into their pages, which can slow down performance and snitch necessary bandwidth. With the following code, you can easily prevent external linking. Replace "yourwebsite.com" with the URL of your website. The last line shows the path to an image that appears instead of the linked picture. You can replace it with any other image. Some really nasty things can be done this way ;-)
1
2
3
4
5
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?yourwebsite.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?yourwebsite.com [NC]
RewriteRule .(jpg|jpeg|png|gif)$ http://i.imgur.com/g7ptdBB.png [NC,R,L]
Please keep in mind that if you have an external feed provider like Feedburner, you may not see any images in the feed.

3. Activate Browser Caching

Hardly any other tuning method achieves as good results as this one with as little effort. Many large files of your website virtually never change. Therefore, it's a good idea to store them in the browser cache. Cached files like CSS or JavaScript load faster as they only have to load once during the first visit. If your visitor returns to the site again (or any other sites for the first time), the browser doesn’t need to reload these files, thus improving the loading performance of the website.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## EXPIRES 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 text/html "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 1 month"
</IfModule>
## EXPIRES CACHING ##

4. Banish IP Addresses Permanently

You may want to banish certain IP addresses, whether it's because someone tried to hack the administrator account or because someone leaves malicious (spam) comments. If you know their IP address, use the following code to banish that person permanently, or at least their IP address, or at least their IP address you know ;-).
1
2
3
4
5
6
<Limit GET POST>
order allow,deny
deny from 123.456.78.9
deny from 987.654.32.1
allow from all
</Limit>
Please keep in mind that you need to replace the IP addresses in the code.

5. Block Include Only Files

There are some really important files that should never be accessible from outside WordPress. Protect your files with the following code:
1
2
3
4
5
6
7
8
9
10
# Block the include-only 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>
Please keep in mind that this code doesn't work with a WordPress multisite installation.

6. Protect the Wp-content Folder

The wp-content folder is the most important WordPress folder as it contains your themes, plugins, images, cached files, etc. This makes it the major target for hackers, so it should be well protected. Create a separate .htaccess file, add the following code and upload the file into the wp-content folder (www.yourwebsite/wpcontent/).
1
2
3
4
5
Order deny,allow
 Deny from all
 <Files ~ ".(xml|css|jpe?g|png|gif|js)$">
 Allow from all
 </Files>

7. Disable the XML-RPC Interface

With the XML-RPC interface, you can manage WordPress with external programs and publish articles or edit comments. These include mobile applications for iOS, Android and Co. as well as Windows LiveWriter and other software. The interface can also be misused for DDoS attacks, which can shut your website down. You should disable the interface with a short entry in .htaccess:
1
2
3
4
<Files xmlrpc.php>
  Order Deny,Allow
  Deny from all
</Files>
Use the above code only if your website has no blog functionality because trackbacks won’t have access either. If you have a blog or want to use your WordPress with mobile applications, use the following code to protect the interface:
1
2
3
4
5
6
7
8
9
10
11
12
<IfModule mod_setenvif.c>
  <Files xmlrpc.php>
    BrowserMatch "Poster" allowed
    BrowserMatch "WordPress" allowed
    BrowserMatch "Windows Live Writer" allowed
    BrowserMatch "wp-iphone" allowed
    BrowserMatch "wp-android" allowed
    Order Deny,Allow
    Deny from All
    Allow from env=allowed
  </Files>
</IfModule>
In this example, the following clients are unblocked (from top to bottom):
  • Poster
  • WordPress blogs
  • Windows Live Writer
  • WordPress for iOS
  • WordPress for Android
Delete clients you don't need. You can also add new user agents and unblock them. Source: Sergej Müller – Protect WordPress XML-RPC interface with .htaccess

8. PHP – Block Error Reports

This is a very important point. When PHP sends an error report, the file path becomes visible. Sergej Müllers describes it as follows: "In WordPress blogs it's fairly easy to (indirectly) create a PHP error to get an error report and path, without being an administrator or expert. Calling up certain WordPress core or plugin files in the address bar of the browser creates PHP fatal errors (because necessary and referenced WordPress functions are missing). If server or PHP settings allow errors to be displayed, they will appear in the browser. Hardly anyone can decrypt error reports, but they are valuable information for hackers to find holes and make full use of them." Solve this problem with a simple addition to the .htaccess file:
1
php_flag display_errors Off

Last, Not Least

You should also block some important files from outside access for the simple reason that you are the only one who needs access to these files. The last code snippet protects your website from URL exploits – URL based attacks. I use this code for all of my websites.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# ----------------------------------------------------------------------
# Important safety settings
# ----------------------------------------------------------------------	

#Block important files from outside access
<files install.php>
Order allow,deny
Deny from all
</files>

<files wp-config.php>
Order allow,deny
Deny from all
</files>

# PROTECT readme.html
<files readme.html>
 Order Allow,Deny
 Deny from all
 Satisfy all
</Files>

# PROTECT readme.html for DE edition
<Files readme.html>
 Order Allow,Deny
 Deny from all
 Satisfy all
</Files>

<files error_log>
Order allow,deny
Deny from all
</files>

# Block URL based exploits 
RedirectMatch 403 [
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Ban double slashes in all URLs 
RewriteCond %{THE_REQUEST} ^[A-Z]+ /(([^/ ]+/)*)/+([^ ]*)
RewriteRule ^ /%1%3 [L,R=301]
</IfModule>

Conclusion

It only takes a few minutes to make your WordPress website safer and faster with these code snippets. While hackers will have a hard time attacking your website, your readers can enjoy a better loading performance; thanks to an active browser caching.

Related Links

 (dpe)

Andreas Hecht

Andreas Hecht is a journalist and specialist for WordPress and WordPress Security. He roams the web since its inception. He has published an ebook on WordPress Security, which you might want to take a look at.

6 comments

  1. Andreas,

    Good article, I will add couple snips I didn’t know about from your article. Thank you.
    One useful code I use a lot lately is to block referee sites from so called “CEO companies”….

    SetEnvIfNoCase Referer somewebsite.com spammer=yes
    SetEnvIfNoCase Referer otherwebsite.com spammer=yes

    Order allow,deny
    Allow from all
    Deny from env=spammer

  2. Obviously a very innovative as well as informative step to prevent the trespassers as being developer all WordPress developers needs to be aware of it to ensure the security of websites.

  3. Hello, thank you for the article. And just one thing I noticed, in the end, in your author box (about the author), the link that would take to your ebook, it doesn’t go to your ebook page, I am directed to the front page of the online bookstore.

  4. Useful snippets indeed, but I do not trust some of these as a real protection:

    4. Banish IP Addresses Permanently: Usually an attacker is behind a proxy, so the “ban by IP” should be something temporary and better managed by solution like FailToBan or similar.

    7. Disable the XML-RPC Interface: BrowserMatch is based on the User Agent, so actually a real attacker already knows how to spoof it.

    8. Last, not least: “PROTECT readme.html for DE edition”. What is the difference with the EN version in this snippet?

Leave a Reply

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