Using .htaccess to Secure and improve WordPress

By | 28 September 2007

Although .htaccess is only a file, it can change settings on the servers and allow you to do many different things, the most popular being able to have your own custom 404 error pages. .htaccess isn’t difficult to use and is really just made up of a few simple instructions in a text file. Nevertheless, it can greatly improve your site’s security, so there’s almost no excuse in using it.Creating a .htaccess file may cause you a few problems. Writing the file is easy, you just need enter the appropriate code into a text editor. You may run into problems with saving the file. Because .htaccess is a strange file name (the file actually has no name but a 8 letter file extension) it may not be accepted on certain systems (e.g. Windows 95). With most operating systems, though, all you need to do is to save the file by entering the name as: .htaccess” (including the quotes). If this doesn’t work, you will need to name it something else (e.g. htaccess.txt) and then upload it to the server. Once you have uploaded the file you can then rename it using an FTP program.

Although there are many things you can do with an .htaccess file, this post will focus on securing WordPress, the CMS used to write articles and posts on this site.

  1. Protect the .htaccess itself (security). This prevents users from reading/writing the file and hence, changing security settings.
    <files .htaccess>
    order allow,deny
    deny from all
    </files>
  2. Hide the Server’s digital signature off (security). This hides the server signature, so intruders will have a harder time trying to find security holes, since they don’t know what’s behind the server.
    ServerSignature Off
  3. Limit file upload size. This helps to prevent DoS attacks (users uploading huge files that may crash the server) and saves bandwidth.
    LimitRequestBody 10240000
    # limit file uploads to 10mb
  4. Disable mod_security filtering. This is an optional setting and must be handled with care. This directive tells the server not to use mod_security’s filters, which, for instance won’t allow users to post a text with the words “curl”, “lynx” or “wget” in them. While this might seem trivial, it can be a headache in a site like this one, where these words are typed almost on a daily basis.
    SecFilterInheritance Off
  5. Protect wp-config.php. Just as with .htaccess, we prevent users from reading/writing WordPress’ configuration main configuration file. This directive assumes WordPress is setup on the site’s root folder.
    <files wp-config.php>
    order allow,deny
    deny from all
    </files>
  6. Specify custom error documents. This directives have to do with site usability rather than security. They determine which pages will be displayed in case of server errors, such a Page not Found (code 404), Forbidden access (code 403), etc.
    #custom error docs
    ErrorDocument 404 /notfound.php
    ErrorDocument 403 /forbidden.php
    ErrorDocument 500 /error.php
  7. Disable directory browsing. This prevents the server from displaying folder contents when no index file (index.html, index.php, etc.) is found. This prevents users from seeing the folder contents and makes it harder to mount an attack against the site.
    # disable directory browsing
    Options All -Indexes
  8. Disable Image hotlinking. This prevents other sites from linking to our site’s images, forcing them to either point to the entire page or host the image somewhere else. This saves precious bandwidth and may increase traffic (just a tiny bit). The code below will display image stealingisbad.gif whenever someone tries to display our images by hotlinking to our site.
    #disable hotlinking of images
    RewriteEngine on
    RewriteCond %{HTTP_REFERER} !^$
    RewriteCond %{HTTP_REFERER} !^http://(www\.)?yourdomain.com/.*$ [NC]
    #RewriteRule \.(gif|jpg|png)$ http://www.yourdomain.com/stealingisbad.gif [R,L]
  9. Sets the canonical or “standard” for every URL at your site. This helps improving the site’s usability and also helps in improving the site’s Search Engine rankings. In short, it redirects all requests of the form: http://yourdomain.com to http://www.yourdomain.com/.
    # set the canonical url
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^yourdomain\.com$ [NC]
    RewriteRule ^(.*)$ http://www.yourdomain.com/$1 [R=301,L]
  10. Protect the blog from Spam comments (and spam form submission in general). This last directives will prevent users from posting forms (such as comment forms) directly from other sites. Although this is hardly a catch-all antispam measure, it helps.
    # protect from spam comments
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} POST
    RewriteCond %{REQUEST_URI} .wp-comments-post\.php*
    RewriteCond %{HTTP_REFERER} !.*yourdomain.com.* [OR]
    RewriteCond %{HTTP_USER_AGENT} ^$
    RewriteRule (.*) ^http://%{REMOTE_ADDR}/$ [R=301,L]

After these directives, you should add whatever WordPress writes for managing Permalinks. There are much more directives left and many more ways to use this little file to improve and secure a website but this should account for most of the everyday needs. After you upload the file to your server, test, test, test and when you think everything’s working fine… test again. Check whether “protected” files can be accessed and that you can still access “allowed” files and folders. Regular expressions can be a tricky thing, and they can lead to seemingly random problems, so make sure you test your site thoroughly before releasing it to a production server.