Tuesday, March 21, 2017

SECURE WORDPRESS SITES

How to secure WordPress – A definitive checklist for webmasters and WordPress hosting providers


WordPress takes security very seriously. As of June 18, 2016, WordPress has released 22 “minor” revisions, most of which fixed vulnerabilities reported just hours before. In WordPress v4.5+ websites that have automatic background updates, these fixes were installed instantly preventing any possible exploits. Even with such a proactive approach towards security, news vines are flush with reports of WordPress sites affected with one vulnerability or another. So, what’s the deal here? How can you protect the WordPress sites you manage?
Listed here are the common ways in which WordPress sites are hacked.
    • Exploiting un-patched WordPress vulnerabilities
    • Exploiting un-patched vulnerabilities in themes and plugins
    • Exploiting vulnerabilities in hosting environment
    • Using stolen login credentials
Now let’s address each of these issues one by one and look at the solutions available to mitigate them. I’m going to lay off using plugins as much as possible because even security plugins are known to have vulnerabilities. We’ll employ defense in depth (or multi-layered defense), security by obscurity (denying target information), access restriction and penetration testing in this checklist.
Use the index here to skip to your favorite topic:

Securing WordPress core


As mentioned earlier, WordPress is serious about security, and come bundled with a lot of security options that works out of the box. Along with it, we’ll add a few hosting level security to make your WordPress extra secure.
how to secure wordpress

Use non-standard table prefix

By default WordPress uses “wp_” as a prefix for all tables. Mass SQL injection exploits depend on this prefix to work. So, changing this at installation time to something else, like “mysite_” is a good hedge against un-disclosed exploits. If you have already installed your site, don’t worry, just carry on with the rest.

Put wp-config.php outside document root

Due to vulnerabilities in hosting environment, hackers might be able to download wp-config.php, thereby disclosing your database login details. WordPress by default looks at the parent directory for wp-config.php. So, just move it there for an additional layer of security.

Remove “admin” user

Hackers know “admin” is a popular username for administrator privilege accounts. So, most brute force attacks just focus on getting the password of “admin” user. If your WordPress has an “admin” user, create another user with administrative privilege (with a nick name different from username). Re-assign all posts of “admin” to the new user and delete the “admin” user. There, you’ve denied another angle of attack.




Password protect “wp-admin” directory

Most brute force attacks depend on “wp-admin” folder being readily accessible. Password protecting the “wp-admin” directory will blunt those attacks. To do this, enter this code into an .htaccess file in your “wp-admin” folder (change the file path as applicable, but make sure it’s outside docroot).
ErrorDocument 401 default
AuthType Basic
AuthName "Only Admins"
AuthUserFile "/home/username/private/wpadminpasswd"
AuthGroupFile /dev/null
require valid-user

Order allow,deny
Allow from all
Satisfy any

Then head over to htaccesstools.com
, and generate an htpassword combo, which would look something like this:
jlennon:$apr1$I/HgtJ/B$qufkBuJSJlnF4XGhnYxDQ.
Put this into the file /home/username/private/wpadminpasswd, and you are done! If you run a multisite, make a password for each of your users as they sign-up. It’s a small price for security.

Lock down files and directories

Permissions of all files and directories should be limited to 644 and 755 respectively. This blunts many malware upload attempts. If you have shell access, use the below commands to recursively fix the permissions. Else, you’ll have to download your site files via FTP, fix the permissions, and re-upload it.
# find /home/username/docroot/ -type f -exec chmod 644 {} ;
# find /home/username/docroot/ -type d -exec chmod 755 {} ;

Replace default WordPress security keys

WordPress uses password “salts” to improve encryption in visitor’s cookies. It’s trivial for hackers to determine the default keys shipped with each version. So, get a different set of keys from https://api.wordpress.org/secret-key/1.1/salt/
 and replace the old ones in your wp-config.php. It’ll look something like this:

Wordpress secret key in wp-config.php
WordPress secret key

Update WordPress on the release date

I’ll say that again. Do not wait till later. Upgrade your WordPress as soon as you see the message “WordPress XX.YY is available! Please update now” in your admin panel. Test it on your staging server, and roll out the update as soon as you can.
If you are sure your themes or plugins won’t be affected by a WordPress core update, enable auto update by adding the below configuration entry in your wp-config.php.
define( 'WP_AUTO_UPDATE_CORE', true );
If you want a notification mail when an update is available, install WP CLI (or get your host to install it for you), and put the below command as a cron job:
php /path/to/wp-cli.phar --path=/path/to/wordpress/ core check-update | mail -s "WP update" your@email.com

Disable file edit via admin panel

Plugin and theme editor in the WordPress admin panel is a favorite tool used by hackers to insert malicious code into websites. You can disable that editor by adding the below configuration entry in your wp-config.php. Your customers can still use their FTP to make changes to files.
define( 'DISALLOW_FILE_EDIT', true );

Disable pingbacks and trackbacks

If not absolutely necessary to your service offering, consider disabling pingbacks and trackbacks. This can be used for DDoS attacks against your site. In your admin panel, go to “Settings” –> “Discussion” –> “Default Article Settings”, and tick off “Allow link notifications from other blogs (pingbacks and trackbacks)”.

Enable comment moderation

Some kinds of attack relies on directing visitors to a malicious website through a comment link. Holding the comments for moderation is a good hedge to that. In your admin panel, go to “Settings” –> “Discussion” –> “Default Article Settings”, and enable “Comment must be manually approved”.
Disable pingbacks and trackbacks in wordpress
Disable pingback requests and moderate comments

Clean out docroot and user list regularly

There shouldn’t be any file in the document root that isn’t part of your current site. It is common to see .sql files, .tgz files, backup files, etc. in document root, and they are an easy way for hackers to gain critical information or even access to your database. Audit your site periodically and delete all files that aren’t essential.
In your audit take a look at the user list as well. Remove all users who un-subscribed or stopped using your service. Their passwords would be stale and is a convenient entry point for hackers.
If you’ve done all the above, the WordPress core installation is reasonably secure. We’ll now see how to keep your plugins and themes secure.

Securing WordPress themes and plugins


A look at the OSVDB WordPress vulnerability list shows that 554 out of 562 vulnerabilities reported in 2015 are from a third party theme or plugin. That’s 98.6% of all WordPress vulnerabilities. It’s an indicator of how big a security risk it is when you decide to install an additional theme or plugin in your site. Let’s take a look at how you can mitigate the risk from third party integrations.

Minimize third party integrations

Keep the number of themes and plugins installed in your site to a minimum. Be ruthless about it. If you can get a plugin that combines the features of two others, get rid of those two. If you can use a server level script to get some data you need, use that instead of a plugin. Remember, with each additional line of code, the risk of a bug being present in your site increases.

Use only professional, reputable, well-maintained plugins and themes

Keeping a piece of software is hard work. It takes time and effort. As a site maintainer, it’d be safe for you to use only those themes and plugins that meet the criteria below:
  • That is published in WordPress.org. This makes sure that the theme or plugin won’t have malware.
  • That is updated frequently. If it hasn’t had an update in the past 6 months, think twice about using it.
  • That doesn’t have a long history of vulnerabilities. Just google for “[plugin name] vulnerability”, and see the list for yourself.
  • That is recommended by a lot of people. The more reputable a plugin is, the more the programmer has a stake in ensuring its quality.
  • That is paid and supported by a reputable group.

Update on the day of patch release

I can’t stress this enough, but I guess you get the point. Keep a close watch on the available updates, and upgrade the plugins and themes as soon as a patch is available. If possible, configure auto-updates to your plugins and themes. You can fine tune auto-updates to allow only security updates as mentioned in the Codex link here: https://codex.wordpress.org/Configuring_Automatic_Background_Updates

If you want to be notified when an update is available, install WP CLI (or get your host to install it for you), and put the below commands as a cron job:
php wp-cli.phar --path=/var/www/bob/ plugin list | grep available | mail -s "WP plugin update" your@email.com
php wp-cli.phar --path=/var/www/bob/ theme list | grep available | mail -s "WP theme update" your@email.com
There’s more that you can do to ensure security of your theme and plugins, but it’s done at the hosting level, which we’ll cover next.

Hosting environment security


If you are a webmaster with access to a VPS, cloud instance or a dedicated server, or if you are a hosting service provider yourself, this section is applicable to you. We’ll go through all that can be done at the hosting level to improve security.

Review general server security

There’s a lot that can be said about general server security, and is out of scope of this article. I’ll list down the main points here that needs to be checked off:
  • Strict server update regime. As soon as an update it available it should be installed.
  • A well configured firewall. Something like CSF or APF would do.
  • Turn off server signatures to deny access to server software information.
  • Brute force attack detection and prevention. Something like BFD should do.
  • DoS mitigation steps. Something like mod_evasive should be OK.
  • Configure webserver to limit the access of one user is limited one docroot. Eg: Use SuPHP or mod_ruid2.
  • Anti-spam security that prevents open relay, mail rate limit, outgoing filtering and incoming filtering.
  • Basic network and file system security. Proper permissions to make sure people get to only those places they are supposed to.
You can read more about server security in the following links:

How to harden a cPanel server

Anti-malware checklist for web hosts

Secure your database access

Select a complex username and password for the WordPress database. It’s anyway stored in a configuration file, and you don’t have to remember it. Also, when granting access to the user give only the minimum needed privileges, that is, SELECT, INSERT, UPDATE and DELETE.

Disable dangerous PHP functions

There are a few favorite PHP functions used in exploits. Disabling them will prevent execution of malware. Find your php.ini and make these changes:
disable_functions=exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
allow_url_fopen=Off
allow_url_include=Off

Block malware uploads using scanners

Open source malware scanners go a long way in detecting malware before it can pose a threat to your site. ClamAV and Linux Malware Detect (LMD) are a couple of good ones I’ve used. You can club the virus databases of these together, and even beef them up with free rules from SaneSecurity.

Block exploit attempts using a Web Application Firewall

The most popular open source WAF is mod_security. You can get free rule sets in OWASP and from ComodoWAF. A properly configured WAF will block a lot of exploit attempts, brute force and comment spam before they reach your site. To make it even more secure, link it up with a malware scanner enginer (like ClamAV) so that each upload will be scanned for malware signature.

Block XMLRPC attacks

As we’ve discussed in an earlier article, you can block XMLRPC attacks
 by adding this rule in mod_security:
#Block requests to xmlrpc.php with no referring URL
SecRule REQUEST_METHOD "POST" "deny,status:401,id:5000900,chain,msg:'xmlrpc request blocked, no referer'"
SecRule &HTTP_REFERER "@eq 0" "chain"
SecRule REQUEST_URI "xmlrpc.php"

Monitor file changes

The “Real-Time Monitoring” feature in Linux Malware Detect (LMD) can be used to monitor the files in your WordPress docroot, and send you a mail if a file is changed. Just run it in monitor mode. It can come in quite handy in detecting malware uploads via stolen FTP passwords.
maldet --monitor /path/to/wordpress/
If you have WP CLI installed you can check if WordPress core files were changed by running this command in cron:
php wp-cli.phar --path=/var/www/bob/ core verify-checksums | mail -s "WP change check" your@email.com

Configure backup, verify integrity daily

Configure a reliable backup system. It should ideally backup your files and database at least once a day. Here’s a primer on how to define your backup policy
 and what all should be done to ensure a reliable backup
. A good backup is one that you KNOW is working. For that, you need to check its integrity with random restore tests once a day. Bash or Perl scripts can be used to automate this task.

Scan for vulnerabilities

You can take a pro-active approach in detecting vulnerabilities with your website. There are open source tools like WPScan and Nikto that can tell you if your WordPress has a vulnerable theme or plugin. For example, a sample WPScan output looks like this:
wpscan WordPress security scanner
WordPress vulnerability scanning using WPScan
You can specifically scan for vulnerabilities in your themes and plugins using these commands and have it mail you.
wpscan.rb --update && wpscan.rb --url https://yoursite.com
 
 --enumerate vt vp
There’s more that can be done, like blocking out all no-referrer accesses, enabling two factor authentication, blocking IP ranges, etc. But, we’ll limit our hardening steps to what doesn’t have negative side effects.

Mitigating user level vulnerabilities


It is said that security is only as strong as the weakest link, and we’ve seen that users with inadequate awareness of security is a big risk. As a webmaster or service provider there isn’t a lot that you can do to prevent your users falling prey to phishing, or getting key loggers installed in their laptops. But with a combination of server policies and education, you can mitigate a few of those risks. We’ve covered some of that in earlier sections, like automatic core updates, file upload scanning, etc. We’ll cover the rest here.

Educate about strong passwords

The oldest, yet one of the most vulnerable hacker entry points. People tend to choose passwords they can easily remember, and that’d usually be a variation of their username, publicly available information or dictionary words. From v4.3, WordPress generates a strong password for the user by default. Encourage customers to use that.
Generate secure WordPress passwords
Generate strong passwords in WordPress
If they prefer to create their own passwords, here’s a very effective method proposed by XKCD to create memorable, complex passwords:
How to choose a strong password
How to choose a strong password

Educate about phishing and computer security

Put up a page on your site listing the common phishing scams and how hackers can install keyloggers and RATs on laptops. Encourage them to update their software frequently and to use a personal firewall + anti-virus on their system.

Enforce SSL

One common way for hackers to get passwords is by snooping on insecure WiFi hotspots. You can blunt that by enforcing SSL for admin access. Just put this in your wp-config.php (after setting up a certificate on the site, of course – your customers should have at least a shared SSL).
define(’FORCE_SSL_ADMIN’, true);

Restrict plugin installs

If your business model can afford it, restrict new installs of plugins and themes. In services like managed WordPress hosting, this is possible. To disable plugin/theme installs and edits, put this in your wp-config.php:
define( 'DISALLOW_FILE_MODS', true );
That’s about it. Once you’ve implemented all of the above, you have a pretty secure WordPress installation. There’s of course more than can be done to beef up security even further (security plugins, third party malware monitoring, etc.), but doing the above should lock down your WordPress pretty tight. If you have any suggestions, we’d be happy to talk to you.

No comments: