User Tools

Site Tools


cms:wordpress-security-tips

WordPress Security Tips

Difficulty
Medium
Medium

It is highly recommended to ensure your WordPress is backed up regularly, especially if making any core changes as advised in this article. For cPanel servers, you can learn more about the configurable automatic backups here.

This article will cover many recommended methods to secure your WordPress installation. The latest version of WordPress can always been found on their official download page: Download WordPress or Latest WordPress Zip Archive. WordPress has a much more extensive treatment of the topic in their documentation. Here we go over some of the most basic measures you can take to help ensure the security of your site.

Keep WordPress Updated

One of the most vital and important issues, is to ensure that your WordPress install is kept fully updated. Older versions of WordPress can be exploitable, leaving your website and sometimes server vulnerable to attacks or malicious activity. Further, almost every updated version of WordPress specifically references security patches.

We have an article available for upgrading WordPress available here: How can I upgrade WordPress? Since WordPress 3.7, automatic updates have been enabled by default and more information regarding these automatic updates can be found here: Configured Automatic Updates.

Besides keeping the actual core WordPress install updated, keeping plugins and themes fully updated is just as important, if not even more important. In the WordPress Admin Panel, the plugins page and themes page will both advise if plugins or themes need to be updated. Check out the screen shots below for examples of plugins and themes that have updates available.

Strong Passwords

Always make sure to use strong passwords for any authenticated access. For example, your admin user (which shouldn't be named admin, if it is change it!) and your MySQL database passwords. You can see more about secure password generation in our How can I generate ... ? article.

Choosing Plugins for WordPress

We all have our list of favorite plugins, however we rarely check to see if those plugins have any added vulnerabilities, besides WordPress's own vulnerabilities. However, often times it's the plugins and themes that can make it even less secure. If you find a plugin that you feel you need to install, make sure you research the plugin first, verifying that no exploits or vulnerabilities exist for it. Similarly, many themes have plugins builtin to them, so you will want to research these carefully as well. For example, a couple years ago there was a vulnerability in revslider that was patched, but many themes had bundled it in and didn't update it to apply the patch. So a lot of site administrators were vulnerable to the exploit and didn't even realize they were running the plugin. So you will want to carefully research each plugin and theme you consider before installing.

Security Plugins

Here's a list of suggested Security Plugins that can help with your WordPress security:

  • WordFence has several useful features, including checking the core files–as well as the plugin and theme files–for changes likely to indicate site compromise. It can also be configured to send you an email when either the WordPress core or any of the installed plugins or themes have updates available. It also can throttle certain types of traffic to reduce server load, and lock out IP addresses that pretend to be Google that aren't. You can read more about this plugin on their page in the WordPress plugin catalog. But, one thing that WordFence does not do, is log the failed logins in files where they can be read, for example by CSF/LFD. Which brings us to:
  • WP-fail2ban is a plugin that causes login successes and failures to be written to server logs, so that firewalls like CSF/LFD can be configured to read it. The plugin is designed to work with a firewall called Fail2Ban1) which conflicts with CSF/LFD2), but CSF/LFD can be configured to read the logs for the entries generated by this WordPress plugin.3)

Disabling Unnecessary Files & Access

The default WordPress installation retains numerous files in the installation path that can provide information to potential hackers. For example, the readme.html in the document root of the WordPress installation provides the installed version. The installed version may contain vulnerabilities, allowing the attacker to pinpoint an exploit point. You can check if your site has this problem as follows:

$ curl -s http://domain.tld/readme.html | grep Version
<br /> Version 4.0.1

This is just one example. It is recommended to disable access to the following files:

  • All license* files. Including the ones provided in plugins and/or themes.
  • All readme* files. Including the ones provided in plugins and/or themes.
  • wp-config-sample.php
  • xmlrpc.php4)

You could remove all of these files, however a simple way to simply remove permissions or access to these files would be to remove permissions on the file(s). For this example, we will be chmodding all of the referenced files to 000. Which can easily be done via shell terminal using the following examples. Note: You'll want to replace /home/user/public_html/wordpress/ with the absolute path to your WordPress install's document root.

It is recommended to run the find commands for a list of files before actually changing permissions to ensure all files are safe to disable.

# find /home/user/public_html/wordpress/ -type f -iname "*readme*" 
# find /home/user/public_html/wordpress/ -type f -iname "*license*" ! -iname "*.php"
# find /home/user/public_html/wordpress/ -type f -iname "*readme*" -exec chmod 000 {} +
# find /home/user/public_html/wordpress/ -type f -iname "*license*" ! -iname "*.php" -exec chmod 000 {} +
# chmod 000 /home/user/public_html/wordpress/wp-config-sample.php /home/user/public_html/wordpress/xmlrpc.php

Disabling PHP Execution from wp-content

Many exploits, especially due to plugin vulnerabilities, operate in part by running php scripts from directly within the wp-content folder, or even the uploads folder itself. The WordPress core files do not need to run any php scrpits directly from these folders. Some plugins may, but keep in mind that these are often the same plugins that more often will have this type of vulnerability. To help protect against this type of exploit, you may want to add the following lines to an .htaccess file in the wp-content directory:5)

<FilesMatch "\.php$">
Order Deny,Allow
Deny from All
</FilesMatch>

This may break some themes/plugins depending on how they work. If you experience issues, simply remove that htaccess rule.6)

Disabling Directory Index Listing

Many servers default to allow directory index listing. For example when visiting a typical WordPress install, if you add wp-content/plugins/ to the address,7) you would be able to see all plugins on the site as well as the files within the directories. To ensure this option is not available, place an .htaccess file containing

Options -Indexes

in your wp-content and wp-includes directories.

$ echo "Options -Indexes" >> /home/user/public_html/wordpress/wp-content/.htaccess
$ echo "Options -Indexes" >> /home/user/public_html/wordpress/wp-includes/.htaccess 

Alternatively, if you would like to disable directory index listing serverwide, this can be done8) in WHM at Home » Service Configuration » Apache Configuration » Global Configuration as described here, by making sure the "Indexes" box is not checked, in the Directory "/" Options section.

Disabling Theme / Plugin Editing

While this is a user friendly feature of WordPress, it also opens your installation to overlooked vulnerabilities. This option removes the ability for the WordPress installation to edit plugins or themes. It is recommended to ensure your website is finished with development and then add the following constant to your wp-config.php file.

define(‘DISALLOW_FILE_EDIT’,true);

Of course, if you have this constant enabled and would like to turn the feature back on, you can simply comment out the constant from your wp-config.php file.

Securing Themes

Check your installed theme's header file for the following:

<meta name="generator" content="WordPress <?php bloginfo('version'); ?>" />

If this line of code exists, remove it or comment it out. This will disable the theme from providing version enumeration.

Disable Login Errors

Login errors can provide useful information to hackers. For example, if they use a correct username, it will respond with invalid password, but at now they know they've used a correct username to keep trying with. To disable this, add the following code to your installed theme's functions.php:

add_filter('login_errors',create_function('$a', "return null;"));

Replace Original Authentication Unique Keys and Salts

Your wp-config.php file contains authentication keys and salts. You can regenerate and replace the existing keys and salts at any time, forcing all users to log in again. It is recommended to do this occasionally. Lines 45-82 of wp-config.php will contain these keys, looking similar to the following:

define('AUTH_KEY', '/asT;[zOn.E~|d~Dh*{zf./31s&n-%vry7I*x+Ddz%h_Pu,#;%,;01+2=:@[email protected])UC!Zts');
define('SECURE_AUTH_KEY', 'zp{Re)}Rdnexx{?ujlN[+tWJrTXr$z+s1DKfj4cegdPo:]h12B=5j?fRlRhiGh`-');
define('LOGGED_IN_KEY', '~=GX1e<~$R3aIN8Vy,+Ddz%hlR.S!/e<e!fvWdRkrM~KjoB}xmA*hwr=E[]gC~U');
define('NONCE_KEY', 'x QECT!B~d)+^[email protected]+:A/`p+Ddz%h*,/rf;d~#gaLRz p[yO8+-P%B<Sga[+=sCKj');
define('AUTH_SALT', '[email protected]%,ca:22w^y=iHGGWw8>xD%(6-fS4+gj.ulHKh%h%UeXFHw#m0:]0RbX-{NL_~p');
define('SECURE_AUTH_SALT', 'b[,[email protected]#)y8/[email protected][n?+5k!Rh%i#$9 o$pe >5i=|G?~mHnLsG-7+');
define('LOGGED_IN_SALT', 'HfJe:G!A6q>kSu>To 9W;YxCY?73K Pk3;ih%-)H7Dpn#j>[email protected],CVT&yn+$/]');
define('NONCE_SALT', '[email protected] t_&KRIjgEfsUbR|bo>^Q~$LYo*,W#G<R0+Ih%l`g1X?:*>V`_vb3Ii9+z}eJt');

Change Default 'wp_' Database Prefixes

Using the default, predictable wp_ prefixes in your database make SQL injections much easier. Altering these prefixes can help secure your WordPress installation even further. It's best to ensure this is done during the WordPress installation, doing it after is much more difficult, however I've outlined the steps required here.

  1. Update the table_prefix constant in wp-config.php to the new prefix. The line looks like this:
    1. $table_prefix = 'wp_';
  2. For this example, we're changing wp_ to wp_khsec_.
    1. $table_prefix = 'wp_khsec_;
  3. Using either PHPMyAdmin or MySQL via command line, you'll now have to rename all tables in the WordPress database to the new prefix.
    1. mysql> show tables;
      +-----------------------+
      | Tables_in_securewp_wp |
      +-----------------------+
      | wp_commentmeta        |
      | wp_comments           |
      | wp_links              |
      | wp_options            |
      | wp_postmeta           |
      | wp_posts              |
      | wp_term_relationships |
      | wp_term_taxonomy      |
      | wp_terms              |
      | wp_usermeta           |
      | wp_users              |
      +-----------------------+
      11 rows in set (0.00 sec)
    2. mysql> RENAME TABLE wp_commentmeta TO wp_khsec_commentmeta;
    3. This will need to be done for each table in the database.
  4. Lastly, a few tables have fields that need to be updated as well. Ensure that you modify these fields:
    1. wp_khsec_options > wp_user_roles
    2. wp_khsec_usermeta > wp_capabilities, wp_user_level, wp_autosave_draft_ids
    3. wp_autosave may not be in your tables.

Ensure Secure Server Side Permissions

Ensuring that your server is using proper server side permissions is a critical topic, but may require some contemplation to choose what's right for you.

The typical recommendation for your PHP Handler is suPHP,9) which requires permissions of 644 for files and 755 for folders. But, we want to make sure we don't add unneeded permissions to files we specifically removed some of the permissions from above. To ensure all files and folders have the correct permissions in your WordPress installation, you can perform the following:

find /home/user/public_html/wordpress/ -type d -perm /022 -exec chmod -c go-w {} +
find /home/user/public_html/wordpress/ -type f -perm /133 -exec chmod -c a-x,go-w {} +

This should remove permissions that shouldn't be needed for any file or folder while using suphp10) without re-adding permissions that were purposefully removed.

As before, replace /home/user/public_html/wordpress/ with the full path to the WordPress site's documentroot.

1)
hence the plugin name
2)
which our servers come with by default
3)
More information on this coming soon!
4)
If you are actually using xmlrpc.php, then you can use more specific .htaccess directives to permit access to it specifically from only where it is needed. More on this here.
5)
or possibly only in the uploads directory itself, depending which plugins you require
6)
though in that case you may want to re-research and reconsider use of the plugin or theme
7)
ie, a url like http://securewp.com/wp-content/plugins/
8)
in cPanel servers
9)
or dso with mod_ruid2 installed
10)
or dso with mod_ruid2 enabled
cms/wordpress-security-tips.txt · Last modified: 2017/11/16 18:55 by Daniel P.