Skip to main content
Dublin Library

The Publishing Project

Security Hardening WordPress

 

WordPress security is as good as you make it and you can always make it better. This post will discuss tools and techniques for making your WordPress installation more secure. Some of these are default choices in WordPress but some are not only not the defaults but you have to manually add to configuration files or .htaccess files. Some of these rules will make local development harder as we expect constant change. However, these are excellent for production sites where we don't expect major changes and we expect them to be slower in adopting new code. This post links to third party plugins in the WordPress Plugin Directory. They are what I use and they've proven good for my use. Please, always test third party plugins and themes on a development environment away from production data and users. ## Disable automatic registration The first idea is an easy one. Disable automatic user account creation for your site. Yes, I get that we're disallowing legitimate users from logging in to the site but I consider this a fair price to pay to prevent bots and other bad actors from running crazy on my sites. It happens that this is the easiest task to complete. From Inside the Administrator, Interface go to **_General_** and about midway down the screen, you will see the option to allow anyone to register and a pulldown menu to indicate the new user's default role. ![](https://res.cloudinary.com/dfh6ihzvj/images/v1602889862/publishing-project.rivendellweb.net/hardening-fix/hardening-fix.png) WordPress settings for membership and new user default role. Make sure that the default values shown in the figure above remain as they are unless you're ready to do the work of managing users and their roles. Unless you have a lot of users you can create accounts and assign roles manually. ## Check file permissions The next item on my list is to check the permissions of the files in my WordPress installation. If you are used to the octal three-digit representation of Unix permissions we want our directories to have permissions of 755 and our files to have the permission of 640. We don't want anyone but the owner of the files, the user who WordPress was installed under, to have access to the WordPress files. ## Protect configuration file from direct access Next on the list, we need to make sure that our configuration file, `wp-config.php` is not readable by anyone who doesn't need to. The configuration file contains the name and credentials for the WordPress database and the salt for all our security tools like nonces. To disable access we add the following code to the `.htaccess` file at the root of our WordPress installation. Make sure this code is at the top of the file, before the generated code for permalinks. ```apacheconf # Apache < 2.3 Order allow,deny Deny from all Satisfy All # Apache >= 2.3 Require all denied ``` ## Use .htaccess to prevent access to files In addition to making sure people can snoop on our configuration file, we need to make sure that they can't guess what files we have stored in our WordPress installation. It uses Apache's [mod\_alias](https://httpd.apache.org/docs/2.4/mod/mod_alias.html) and the [RedirectMatch](https://httpd.apache.org/docs/2.4/mod/mod_alias.html#redirectmatch) directive to redirect a list of indicated files and extensions to a 403 status code, denying access to the requested resource. ```apacheconf # SECURE LOOSE FILES RedirectMatch 403 (?i)(^#.*#|~)$ RedirectMatch 403 (?i)/readme\.(html|txt|md) RedirectMatch 403 (?i)\.(ds_store|well-known) RedirectMatch 403 (?i)/wp-config-sample\.php RedirectMatch 403 (?i)\.(7z|bak|bz2|com|conf|dist|fla|git|inc|ini|log|old|psd|rar|tar|tgz|save|sh|sql|svn|swo|swp)$ ``` With these rules, we make sure that people can't get our backups and other sensitive files directly from the server. ## Prevent administrators from editing theme and plugin files Depending on the situation you may not want administrators to edit themes and plugins from the admin UI. This is particularly important when contractors and other third parties have access to administrative areas and, if allowed, can edit any plugin or theme installed on the server and make unexpected changes and introduce malware to your system. To disable editing, add the following command to your `wp-config.php` if it doesn't exist already. To Reenable editing set the attribute to false or remove it altogether. ```php # 1 RewriteCond %{HTTP_REFERER} !^$ # 2 RewriteCond %{HTTP_REFERER} !^http(s)?://([^.]+\.)?rivendellweb\.net [NC] # 3 RewriteRule \.(gif|jpe?g?|png|webp|woff2|woff)$ - [NC,F,L] ``` The idea behind the fragment is that: 1. If there is a referer, meaning the request comes from a fully qualified URL 2. And the URL doesn't match our domain, in this case, `rivendellweb.net` either in HTTP or HTTPS 3. Then fail all the requests for images and fonts identified by their extension We can add additional extensions to the list in step 3 to make sure we keep our content on our server. ### Consider Two-Factor Authentication Two-factor authentication uses a second means of authenticating you before you're allowed access to WordPress. I ran this [two-factor authentication plugin search](https://wordpress.org/plugins/search/two+factor+authentication/) on the WordPress.org plugin directory. I will not advocate any particular solution. However, if you use [Duo Two-Factor Authentication](https://wordpress.org/plugins/duo-wordpress/) or the [Google Authenticator Plugin](https://wordpress.org/plugins/google-authenticator/) for other two-factor authentication needs, you can leverage those tools with your WordPress installation. Two Factor Authentication presents an interesting issue. Unless you make two-factor authentication mandatory for all users (which would make sense) you'll have to use something like the [Google Authenticator – Per User Prompt](https://wordpress.org/plugins/google-authenticator-per-user-prompt/) or its equivalent for your authenticator so it will only show it to the users who have opted into authentication. ### Consider A WordPress-Based Firewall The last consideration we'll address in this post is whether to add a software firewall in addition to whatever hardware or software firewall your host provides. There are [differences between software and hardware firewalls](https://www.uscybersecurity.net/firewall-hardware-firewall-software/) that should be kept in mind when making the decision. I ran a [firewall plugin](https://wordpress.org/plugins/search/firewalls) query on the WordPress plugin directory for reference. The plugin that caught my attention and I've used in the past is [Block Bad Queries (BBQ)](https://wordpress.org/plugins/block-bad-queries/). The only drawback is that you can't customize the settings, for that you need a [pro version](https://plugin-planet.com/bbq-pro/)

Edit on Github