Share it!

WordPress security is one of the most underestimated factors among bloggers, even some with advanced blogging skills. This short tutorial is intended to provide code snippets that you can add to WordPress’ .htaccess file and help your blog to become more secure.

In a standard, three-click WordPress installation, there are quite a few potential vulnerabilities that are left unattended. For this reason, WordPress websites are the ones hackers try to use to attack and take control of your sites. For instance, allowing directory browsing and not protecting files that could potentially expose vital information are two of the most common problems found in websites, not just WordPress ones.

What is the .htaccess file?

An .htaccess file is an optional configuration file for the Apache webserver to interpret, for each directory. You can store various settings in that file such as: password protect a directory, block specific IPs or file or folder from public access, etc. In most WP setups, the .htaccess file is present in the base WordPress installation directory and it stores the permalink structure by default, as well as caching, redirection and related settings.

First things first: Protect your .htaccess and .htpasswd files

Change the permissions (using either chmod or your FTP client) of your .htpasswd files to 640, .htaccess files to 644. PHP files should be set to 600. Also, change permissions of the files that you really don’t want people to see (such as wp-config.php, config.php) to 400.

Remember, NEVER EVER set permissions of your files or directories to 777, as it would leave unprotected (people would be able to see them, modify them and even executing them). If something requires write access try setting permissions to 766, and if that doesn’t work, set them to 775. This is true for all files, not just .htaccess files.

Prevent access to .htaccess and .htpasswd files

Because of what you did in the previous step, it is higly unlikely that have to do this unless you are working with your .htaccess file for the whole server but it won’t hurt if you do.

# Deny access to all .htaccess files
<files ~ "^.*\.([Hh][Tt][Aa])">
order allow,deny
deny from all
satisfy all

Protect your wp-config.php

The wp-config.php file contains the most sensitive access credentials of your WordPress site, such as database name and access credentials and various other critical data, among other settings. Under no circumstances you want people looking into this file, so you need to protect it from snoopers.

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

Securing directories: Remove the ability to execute scripts

This is cool, as you are basically categorizing all files that end in certain extensions so that they fall under the jurisdiction of the -ExecCGI command. This prevents files from running on the server and sends them to the browser as is. This prevents unauthorized execution of any scripts other than the ones from WordPress (PHP or other executable files, such as bash scripts).

AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi
Options -ExecCGI

Disable Directory Browsing

This is one of the most common security flaws in a WordPress site, one that quite inexplicably hasn’t been fixed over the years. By default, an Apache webserver will allow directory browsing if it doesn’t find an index file such as index.html, index.php, etc..

This leaves all files and folders inside that directory accessible to a visitor, letting anyone to sniff around the wp-content/uploads folder or any other directory which doesn’t have the default
index.php file.

You do not want that because you don’t want people browsing through your media uploads or your theme or plugin files. This flaw makes it easier for ill-intentioned visitors to see what plug-ins you have, snoop around your files (even the ones that you hide from visitors), etc.

If I pick 10 personal or business websites running WordPress, 6-8 of them won’t have directory browsing disabled. This allows anyone to easily sniff around the wp-content/uploads folder or any other directory which doesn’t have the default index.php file. In order to disable directory browsing, you need to add the following lines to the file.

# Disable directory browsing
Options All -Indexes

Filter which files you allow to get from your wp-content folder

In addition to disabling directory browsing, you can also deny access of all file types, except the ones you really want to share from your website. Basically, you can selectively unblock files like JPG, PDF, DOCX, CSS, JS, etc. and deny the rest from visitors.

To do this, paste this code snippet into a new .htaccess file and paste it in the wp-content folder. Don’t place this in the base installation directory – else you’ll mess up your WordPress site.

You can modify this snippet to suit your needs and add/remove any file type to the list. The above list contains the most-used filetypes so it should be OK in most situations.

# Disable access to all file types except the following
Order deny,allow
Deny from all
<Files ~ ".(xml|css|js|jpe?g|png|gif|pdf|docx|rtf|odf|zip|rar)$">
Allow from all

Deny all access to the wp-includes directory

The wp-includes folder contains only the files that make up the core of WordPress (plugins and themes are stored on the wp-content/ directory). That’s why no visitor (including administrators) needs access to the contents of this folder. You can disable access using this following snippet.

# 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]

A word of caution

Using a few cut-and-paste .htaccess hacks to secure your WordPress site seems easy enough and can certainly make it very resilient to attacks.

However, since a missing ‘#’ character or misplaced ‘</IfModule>’ might destroy your site’s integrity, I strongly suggest you to try out each module one by one (if you have a test site, even better) while making a backup of the file. Also, you should take note of the changes, so you don’t need to go through the whole file to see what’s changed before testing each snippet. Don’t complain if you don’t.

Here’s a Github gist will all the rules implemented here.

WOW! This was a long one, wasn’t it? I hope you found it useful.

Share it!