WordPress Security – Complete 17 Step Guide

wordpress security

WordPress is the most popular CMS on the web and is now powering over 26.5% of all websites. Since it holds such a large piece of the market share it brings additional security concerns and increases your risk of attack when vulnerabilities are discovered. Follow our complete guide below on what you can do to harden your WordPress security and help prevent yourself from getting hacked or becoming a victim of the next brute-force attack.

WordPress Vulnerabilities

Where are you at risk the most when it comes to WordPress? Well, according to WP Scan, a black box WordPress vulnerability scanner, there are have been 4618 vulnerabilities (2,355 unique) reported to date. 52% of the vulnerabilities reported were WordPress plugins. WordPress core accounts for 37% and WordPress themes account for 11%. This has also been confirmed by Wordfence findings where they discovered that 55.9% of vulnerabilities came from plugins.

What types of vulnerabilities are they? According to WP Scan,  39% of WordPress vulnerabilities are cross-site scripting (XSS). Here is the breakdown of the rest in order:

  • SQLI: 15%
  • Upload: 11%
  • CSRF: 7%
  • Multi: 6%
  • Unknown: 6%
  • LFI: 3%
  • RCE: 3%
  • FPD: 2%
  • Auth bypass: 2%
  • RFI: 2%
  • Bypass: 2%
  • Redirect: < 1%
  • XXE: < 1%
  • DOS < 1%
  • SSRF: < 1%

And below are the top WordPress versions with the most vulnerabilities. As you can see WordPress 3.8.1 and 3.7.1 have the most security vulnerabilities.

Here are some recommended sites to stay on top of all of the WordPress security vulnerabilities.

WordPress Security 2017

As you can see there are probably a lot more security vulnerabilities than you even thought! They are constantly popping up which means you are always at risk of being attacked or hacked. You can never prevent these things from happening 100% of the time, the best thing you can do is implement the best security practices to protect yourself. Follow the recommendations below to harden your WordPress security.

WordPress Security Index

  1. Keep WordPress and Plugins Up to Date
  2. Smart Usernames and Passwords
  3. Two Factor Authentication
  4. WordPress Security Plugins
  5. Block Bad Bots
  6. Secure Connections
  7. File Permissions
  8. Database Security
  9. Lock Down WordPress Login
  10. Securing wp-config.php
  11. Disable Includes Browsing and File Editing
  12. SSL Certificate
  13. Disable XML-RPC
  14. Disable JSON REST API
  15. Disable File Editing in the Dashboard
  16. Harden HTTP Security Headers
  17. Hide WordPress Version

1. Keep WordPress and Plugins Up to Date

You should always keep your version of WordPress up to date as well as all of your plugins. Developers patch these for a reason and if you fall too far behind you will open yourself up to a lot of vulnerabilities, as hackers generally target older versions. You can always download the latest version of WordPress from wordpress.org. Since WordPress 3.7, WordPress has added automatic updates, which means you will most likely see the update in your dashboard and you can simply click to update.

wordpress update available

It is also recommended to only use trusted WordPress plugins and themes. Get your plugins and themes from the WordPress repository or from well-known companies. This will cause less problems for you in the future.

Always back up your website! If you maintain regular backups this allows you to easily rollback if you are attacked, and restore your website. We also recommend running backups before you update your WordPress version and plugins. If you happen to be on a managed WordPress host many of them now offer one-click staging areas which are perfect for testing updates before you touch your production site.

There are also many backup plugins available which you can use to backup your WordPress site and database. Here are some popular ones:

2. Use Smart Usernames and Passwords

Be smart with your usernames and password in WordPress. Don’t user “admin” as your username and choose a complex password. This is probably one of the best ways to harden your WordPress security, and ironically it is one of the easiest. However many people use something they can easily remember such as “1234567” and end up regretting later when they are caught with a brute-force attack. Remember there are bots constantly crawling the internet and as your site grows they will always be trying to spoof your login. See this guide on how to choose a strong password and this guide on how to change your WordPress admin username.

Around 8% of hacked WordPress websites are down to weak passwords. WP Template

We recommend using a free program like KeePass or KeePassX which allow you to generate secure passwords and store them in a database locally on your computer.

3. Two Factor Authentication

You can also enable two-factor authentication on your WordPress install to further prevent someone from getting access to your site. We highly recommend the free Google Authenticator plugin. It is free for an unlimited amount of users. Simply install the plugin and click into a user account. You can then setup two factor authentication by creating a new secret key or by simply scanning the QR code. Then make sure to mark it “Active.”

Your login page will then have an additional option for your Google Authenticator code.

Here are some additional plugins that feature two-factor auth.

4. Use WordPress Security Plugins

There are a lot of good WordPress security plugins which will lock down your site and help protect you from brute-force attacks. These plugins allow you to block malicious networks, view WHOIS reports on visitors, rate limit or block security threats, enforce strong passwords, scan for vulnerabilities, see which files have changed, implement a firewall to block common security threats, monitor DNS changes, view real-time traffic and much more.

Here are some popular WordPress security plugins:

We highly recommend the free WP fail2ban plugin. fail2ban is one of the simplest and most effective security measures you can implement to prevent brute-force password-guessing attacks. This plugin is very lightweight. Note: you must have fail2ban installed and configured on your server to use this plugin.

There is also another great WordPress security log plugin which we personally recommend: WP Security Audit Log. This is especially useful for multiple author sites and being able to quickly see what pages and posts were last changed.

wp security audit log changes

5. Block Bad Bots

There are always bad bots, scrapers, and crawlers hitting your WordPress sites and stealing your bandwidth. See a comprehensive list of bots at botreports.com. Many of the security plugins mentioned above can work great to block bad bots, but sometimes you might need to do this at the server level. If you wanted to block multiple User-Agent strings at once, you could add the following to your .htaccess file.

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^.*(agent1|Wget|Catall Spider).*$ [NC]
RewriteRule .* - [F,L]

Or you can also use the BrowserMatchNoCase directive like this:

BrowserMatchNoCase "agent1" bots
BrowserMatchNoCase "Wget" bots
BrowserMatchNoCase "Catall Spider" bots

Order Allow,Deny
Allow from ALL
Deny from env=bots

And here is an example on Nginx.

if ($http_user_agent ~ (agent1|Wget|Catall Spider) ) {
    return 403;
}

KeyCDN also now has a feature which you can enable to block bad bots on the CDN side to save money on bandwidth.

6. Always Use Secure Connections

No matter where you are you should always trying to ensure the connections you are using are secure. You should use SFTP encryption if your web host provides it, or SSH. If you are using an FTP client the default port for SFTP is usually 22.

sftp filezilla

Note: Some FTP clients store passwords encoded or in plain text on your computer. Even some encoded passwords can be converted back to the original. We recommend not saving FTP passwords in the client, or setting up what some call a master password.

It is also important to make sure your firewall rules are setup properly on your home router. And remember whenever you work from a public place like an internet cafe or Starbucks these are not trusted networks.

Your web host where your website resides should also be running secured hosting. This means they should be running up to date and supported versions of PHP, MySQL, account isolation, web application firewalls, etc. Be careful with cheap shared hosts as you can run into issues if they are overcrowding servers and sharing IPs.

7. Check File Permissions

To protect your website you want to make sure and use the correct file permissions. Each directory and file has different permissions which allow people to read, write and modify them. If your permissions are too loose this could open up a door for an intruder and if they are too restrictive this could break your WordPress install as plugins and WP core needs to be able to write to certain directories.

Below is an example of a possible permission scheme. All files should be owned by your user account, and should be writable by you. Any file that needs write access from WordPress should be writable by the web server.

/ :  All files in the root WordPress directory should be writable only by your user account, except .htaccess if you want WordPress to automatically generate rewrite rules for you.

/wp-admin/ : All files in the WordPress administration area should be writable only by your user account.

/wp-includes/ : All files in the wp-includes folder should be writable only by your user account.

/wp-content/ : The content in the wp-content folder is usually user supplied and is intended to be writable by your user account and the web server process.

/wp-content/themes/ : If you want to use the built-in theme editor, all files in the themes folder need to be writable by the web server process. If you do not want to use the built-in theme editor, all files can be writable only by your user account.

/wp-content/plugins/ : All files in the plugins folder should be writable only by your user account.

Other directories that may be present with /wp-content/ should be documented by whichever plugin or theme requires them. Permissions may vary. To reset the default file permissions on your WordPress installation, you may use the following commands within a CLI.

find /path/to/site/ -type f -exec chmod 664 {} \;
find /path/to/site/ -type d -exec chmod 775 {} \;
chgrp -R www-data /path/to/site/

Additionally, the WordPress Codex has an in-depth guide on changing file permissions and recommendations for what they should be set to.

8. Database Security

Not only do you need to check permissions on your files but there are also things you can do to harden the security on your WordPress database. The first thing we recommend is using a different table prefix. By default WordPress uses wp_. If you change this to something like x3sdf_ it will make it much harder to guess by an intruder.

You can change your table prefix on the setup screen when you are installing WordPress.

If you already have WordPress installed, you can use of these popular WordPress plugins below to change the prefix or change the database prefix via phpMyAdmin.

The second recommendation would be to change your database name to make it harder to guess.

9. Lock Down WordPress Login Page

Locking down your /wp-admin login page is by far the easiest security precaution you can implement. On most websites there are thousands of failed login attempts per day that you probably never even realized. With many of the security plugins we mentioned above you can actually see a log of how many attempts there are.

And if you are using admin as your username, which you shouldn’t be, don’t be surprised to see a very high number! What can you do? Well, there are a couple things. One is that many of the security plugins allow you to limit the login attempts allowed in their configuration pages.

wordfence login attempts

The second thing you could do is actually change your login URL. There is a great little free WordPress plugin called WPS Hide Login which will do just that. Feel free to get creative and make your login URL something hard to guess. You will instantly see the number of login attempts drop dramatically after doing this.

wordpress change login URL

Using the security plugins you can also limit access to your login URL by restricting it to an IP address in your .htaccess file or even password protect your login page.

10. Securing wp-config.php

Your wp-config.php contains all the necessary information for an intruder to gain access to your database. This is the most important file in your entire WordPress install. There are a couple things you can do to protect it.

  1. You can prevent the file from being accessed by adding a snippet to your .htaccess file.
<Files wp-config.php>
order allow,deny
deny from all
</Files>
  1. You can also move your wp-config.php file to a non-www accessible directory. Some have argued about the benefits of this, but here is a good explanation.

To move your wp-config.php file simply copy everything out of it into a different file. Then in your wp-config.php file you can place the following snippet to simply include your other file. Note: the directory path will differ based on your web host and setup.

<?php
include('/home/yourname/config.php');
  1. WordPress Security Keys handle the encryption of information stored in user’s cookies. By default these are generated randomly for each WordPress install. But if your WP site has gone through a couple migrations or changed hands it can be good to regenerate fresh encryption keys. WordPress actually provides a Salt Key Generator which you can use to obtain a fresh random set of keys. 
    secret keys wp-config file

11. Disable Includes Browsing and File Editing

Another common security issue is that people leave their http://www.domain.com/wp-includes/ directory wide open for browsing. Hackers can easily find potential exploits by sniffing through those files. Or even determine the version of WordPress you might be running, based on included files. If setup correctly this directory should return a 403 forbidden error.

To prevent access simply add the following snippet to your .htaccess file.

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

And if you’re on Nginx use this.

location ~* wp-admin/includes { deny all; }
location ~* wp-includes/theme-compat/ { deny all; }
location ~* wp-includes/js/tinymce/langs/.*.php { deny all; }
location /wp-includes/ { internal; }

12. SSL Certificate

It always comes back around to moving to “secure web.” For eCommerce sites, the reason you need an SSL certificate is because they are processing sensitive data. For other sites the biggest reason for this is your WordPress login page. If you aren’t running over an HTTPS connection your username and password are sent in clear text over the internet. You can see an example in this article on how to actually sniff and capture WordPress logins over unsecured connections using these free tools. Many people will argue that blogs and informational sites don’t need to be running on HTTPS, but how important are your login credentials? Also, many sites have multiple authors logging in from all sorts of different networks, so running over a secured connection can only help harden your WordPress security.

https wordpress login

We wrote a guide on how to migrate from HTTP to HTTPS. Once you are running on HTTPS it is recommended to force SSL usage by adding the following to your wp-config.php file.

define('FORCE_SSL_ADMIN', true);

With the SEO advantages of HTTPs and performance benefits of HTTP/2 there is no reason not to be using an SSL certificate. And with the Let’s Encrypt project moving forward, web hosts and CDN’s are already starting to offer free certs.

13. Disable XML-RPC

A while back there were a number of brute force attacks exploiting XML-RPC in WordPress, as reported by Sucuri. 99% of people most likely don’t use this function anyways and can disable it. There is a great article from Jesse Nickles on how (and why) to disable WordPress XML-RPC.

You can install the free WordPress plugin Disable XML-RPC from the WordPress repository. Basically this plugin disables the XML-RPC API on a WordPress site running 3.5 or above. You can also block access to this file:

Block XML-RPC in Apache

## block any attempted XML-RPC requests
<Files xmlrpc.php>
order deny,allow
deny from all
allow from 123.123.123.123
</Files>

Block XML-RPC in Nginx

## block any attempted XML-RPC requests
location = /xmlrpc.php {
    deny all;
}

You can test to see if XML-RPC is successfully blocked by running it through the WordPress XML-RPC validation service.

14. Disable JSON REST API

Included in WordPress since version 4.4 is the JSON REST API. This is used by a lot of plugin developers to retrieve data using GET requests. But it could also open up your site to DDoS attacks and other things. You can easily disable it by adding the following code to your functions.php file. Note: This may break certain plugins if they are using the JSON REST API. Usually they will warn you if they are.

add_filter('json_enabled', '__return_false');
add_filter('json_jsonp_enabled', '__return_false');

Alternatively you can also download and install the free Disable JSON API plugin if you aren’t comfortable with editing your code. Note: The plugin only uses the filters built into the official WordPress REST API meant for disabling its functionality. So long as your other REST API does not also use those filters to allow itself to be disabled (and it shouldn’t), you should be safe.

15. Disable File Editing in the Dashboard

One last thing that is recommended is to disable file editing from within the dashboard. And we are referring to the files you can normally edit directly from “Editor” under the “Appearance” menu in your dashboard. If you really need to make changes to those files, do it over SFTP.

wordpress disable file editing

To disable this method of file editing, simply add this following snippet to your wp-config.php file.

define( ‘DISALLOW_FILE_EDIT’, true );

16. Harden HTTP Security Headers

HTTP security headers provide yet another layer of security for your WordPress site by helping to mitigate attacks and security vulnerabilities. They usually only require a small configuration change on your web server. These headers tell your browser how to behave when handling your site’s content. Below are six common HTTP security headers we recommend implementing and or updating.

Make sure to check out our in-depth post on HTTP security headers.

17. Hide WordPress Version

Another good suggestion is to hide your WordPress version. Anyone that looks at the source code of your site can easily tell what version of WordPress you are running and if you aren’t good at staying up with the latest updates this can be a welcome sign for hackers.

WPBeginner, came up with a good solution. Simply add this to your functions.php file.

function wpversion_remove_version() {
return '';
}
add_filter('the_generator', 'wpversion_remove_version');

Also, you need to delete the readme.html file located in the root of your WordPress install because this also contains the WordPress version.

Simply login via FTP and delete it.

domain.com/readme.html

Summary

As you can see there are many ways you can harden your WordPress security. From keeping WordPress and plugins up to date, being smart with usernames and passwords, using security plugins, secure connections, database security tricks, locking down your WordPress login page, securing your wp-config.php file, using an SSL certificate and more. Many of these recommendations can be implemented within a matter of minutes and you can rest easy knowing your WordPress site a little more secure from intruders and hackers.

Have any other good WordPress security tips that you think we missed? If so, let us know below in the comments!

Related Articles

WordPress Security – Complete 17 Step Guide was last modified: June 5th, 2017 by Brian Jackson
  • Lot’s of issues come-out. With this great writing i
    wanna share my little experience about WordPress hope will like it. :)

  • Phil Salt

    Another good Security plugin to use is Ninja
    Firewall http://nintechnet.com/ninjafirewall, which works
    before WordPress is loaded.

    If using an FTP client only allow specific ip access to port 22 &
    only allow access through a key, doable with PuTTY.

    • Great, thanks for the tip Phil! Looks like a great plugin.

  • Loujulz

    Wonderful! So simple. Cool to read such a well-considered article! I mostly use http://goo.gl/q7oQ0F to merge my PDFs. I think it also allows you to fill the merged documents.

  • charles

    Hello, this is a very good post on security.
    I like especially the part on moving wp-config files,

    however, it seems that i have encountered some problem of getting it to work as per the above stated settings and methods:

    “To move your wp-config.php file simply copy everything out of it into a different file. Then in your wp-config.php file you can place the following snippet to simply include your other file. Note: the directory path will differ based on your web host and setup.”

    <?php

    include('/home/yourname/config.php');

    this is how i did it, copied out the contents of the original wp-config.php into the new config file, empty the original wp-config and placed the code within

    <?php

    include('/home/yourname/config.php');

    with the pathway defined to where i kept the config.php file

    Anything that i did right or wrong?

  • Nice article @brianleejackson:disqus

    Thanks for referencing Sucuri, because you reference stats I thought you might also want to take a look at our Q1 Trend report: https://sucuri.net/website-security/website-hacked-report it might provide better insights into the impacts vulnerabilities are having in the community.

    Also, as I’m sure you know, not all vulnerabilities are equal. So saying there have been a lot of vulnerabilities would be seen different if differentiating between low and high level issues. XSS is a perfect example of that, half of those disclosures are low level severity issues and not exploitable at scale. Food for thought.. :)

    Thanks for the share, and nice to see KeyCDN sharing these insights.

    Tony

  • Kaspar Lavik

    Outstanding post! Thanks for sharing your great experience through this effective and helpful tips. I found an interesting article regarding WordPress Security here you can find it https://goo.gl/YCVNJB

  • I have just translated my slides about WP security from WordCamp Prague 2016, hope it can be helpful – http://www.slideshare.net/vsmitka/wordpress-securitydefend-yourself-against-digital-invaders

  • IVGuard

    If you need a fantastic plugin that will protect you from malware attacks you can check out IVGuard. It does what the others fail to do:
    https://wordpress.org/plugins/ivguard/
    https://ivguard.net

  • Thanks for the WP plugin recommendations. WP fail2ban + WPS Hide Login make a good security combo!

  • Stephen Steinberg

    Great list! Question though– have you run into any problems when you combine all-in-one security plugins (ithemes security or wordfence) with manual tweaks to wpconfig and htaccess?

    Just put together my own list of wordpress security tips (http://capitolstartup.com/securing-your-wordpress-site-in-9-simple-steps/), and opted to point people specifically to these all-in-one plugins and not suggesting any manual code changes to core files to prevent that issue.

  • Security of your WordPress website is the prime concern for every site or blog owner. Such articles do help in great deal for those who are new to WordPress.

  • Tyrohn White

    Article with good info graphics and which explained every detail. Keep posting articles to spread more information about WordPress.

  • Et Veritas Liberabit Vos

    thanks for post. about readme.html maybe is better to hide it like xmlrpc.php because after upgrade I suppose this is added again.

    Order allow,deny
    Deny from all

  • Et Veritas Liberabit Vos

    For hide wp version there is also:
    remove_action(‘wp_head’, ‘wp_generator’);

  • The tips that you added are so helpful. But for securing WordPress, you need to give more emphasis to the security of your login area. You need to pay more attention on strengthening your admin login area.

  • Vincenzo Re

    Nice article. I found some tips that I had not implemented, such as to disable JSON REST API. Thanks!

    But in my opinion it is given little emphasis to the intrusion detection systems. We always hope that no one will be able to enter our web site, but sometimes shit happens. Having a tool that tells us which files have been tampered or uploaded can be useful for cleaning up the system after it was compromised.

  • Nice article, but blanket blocking each and every IP address from mainland China is not security, it is stupidity.

  • Danial Wilson

    Nice list of plugins. Thanks for sharing.

  • Danial Wilson

    Great Job. Thanks for sharing.

  • Michael Amaral

    Nice Article..Thank you.

Shares
Share This

Share This

Share this post with your friends!