heartbleed

Time to Get Secure: My First Real Foray into WordPress Security

Until a few months ago, I had no idea how big of a deal website security was.

Theoretically, I knew it was important, and as a WordPress developer, I knew older versions of that software to be quite vulnerable to hacks. For the most part, though, I kept both my sites and my clients’ WordPress sites up-to-date, and so I rarely worried about hacking.

My opinion changed completely, though, when I started seeing dozens of articles and emails about the Heartbleed bug pop up in my inbox. All kinds of sites and services were either affected by this issue or deemed it important enough to at least tell me they weren’t affected. This issue seemed pretty serious.

These affected services likely employed dedicated teams to monitor and avoid problems like this. If these companies failed to prevent this problem despite all their funding and resources, I needed to take a hard look at what I was doing to protect my sites. And at the time, I was doing almost nothing.

Step 1: Remove Old Sites

Like a lot of WordPress developers, I was guilty of creating a lot of sites but not removing them when they became obsolete.

Some of these sites were experiments. I wanted to try out a theme or beta test a version of WordPress without affecting one of my main sites. A lot of these sites were for client use; I sometime would whip up a demo site for a potential client. Of those demos, a few became development sites and occasionally, I’d even end up hosting this development site right in the folder it was built in on my own web server.

Regardless of their intent, the vast majority of these experiment and demo sites sat unused for years. And as you probably know, this was a serious security concern.

Growing Pains

Over the last six years, neither WordPress nor I could imagine what lengths hackers would do to gain access to customer sites.

Because of this, WordPress gained an unfair reputation for their software being hackable. As with life, we only learn from feedback, and WordPress has learned quickly by providing users immediate (and now, automated background) updates. Sadly, this reputation for rapid security hole plugging has been much less forthcoming.

As for me, I’ve been even slower to implement security best practices. Sometimes, even the environment where I chose to do my development was sub-optimal.

The fact that I was designing live, as opposed to locally (plus not using version control) should tell you about what type of developer I was: lazy and stupid. Leaving dead and vulnerable sites on my development server only confirmed this fact.

Garbage Day

Unlike a lot of my clients’ web hosting environments, though, my server was never hacked. I guess I took just enough precaution; usually, I’d deactivate these dead sites’ search engine indexing. By making these sites invisible to search bots, I also made them invisible to the type of bots that target websites to hack.

The past doesn’t predicate the future, though, and when those Heartbleed emails poured in, I decided finally to be much more proactive with securing my sites.

Heartbleed doesn’t specifically attack WordPress sites (it actually affects SSL certificates found in encrypted bank, email and other software sites). It still made me worry. If the tool that literally secures secure sites can be violated, then what chance did my old WordPress version 2.3 installations—outdated and all with the same password—stand?

Since they weren’t worth updating, these old sites had to go. I moved them one by one to a child folder (to give me a chance to review) and then deleted the folder en masse. No sites, no security breach, right?

Step 2: Secure the Remaining Sites

Now that I pruned my server, I could easily see all the sites I still hosted. I then went to work in securing them.

My first hard-boiled security experience came from a new client site I rebuilt. The website was ported from an old Joomla project but the redesign was to be completed in WordPress. When it came time to turn the site over, the client also chose to have me to host it.

Because the old site didn’t have pretty urls (i.e. http://yoursite.com/this-article/), I wanted to make sure visitors were finding the posts they were looking for. I installed a 404 error detector plugin that would show me when pages were clicked but weren’t being found.

The site detected many the article 404 errors I expected, but it also display a lot of other links—links that had weird urls like “http://sitename.com/?register”. And there were hundreds of these errors.

Brute Force Attacks

What did this mean? It meant that hackers were aggressively targeting this site (now residing on my web server) and trying to use brute force attacks (typing different password combinations over and over). They were trying to register for the site and gain access to the Joomla admin panel.

Once in the admin panel, the nefarious attacker could then commit any combination of the following:

  • Steal user info (passwords, emails, etc.)
  • Lock the site
  • Change files to redirect visitors to external sites or allow trojan horses (false forms that ask for sensitive visitor information like credit card numbers).

The scary part is that these attacks had been going on for months—if not years. How much longer would it have taken before they were able to crack the password on the old site?

Limit Login Attempts Plugin

I needed to do something to protect this site, but I hadn’t really really encountered hacker attempts on my own server before. The first tool I tried using was the Limit Login Attempt WordPress plugin.

This plugin served as a damper once the hackers learned the site was no longer a vulnerable installation of Joomla. WordPress has its own login urls and techniques and no doubt, the hackers’ methods would change once they realized the site changed, as well.

The Login Limit plugin worked as advertised. In fact, 2-3 times a day I would receive an email telling me that another IP address was being temporarily prevented from accessing the login screen.

Too many login attempts

Too many login attempts

Although I could blacklist reoccurring IP addresses, often the numbers changed and unfortunately, the emails continued.

I looked up some of the IP addresses from the logs and they mostly came from where you’d expect them to: Eastern Europe, Russia or its former republics. Surprisingly, though, quite a few of these attacks came from IP addresses in France. Apparently, France has quite the hacker culture, too.

Knowing where the hacks came from didn’t help me. What I really wanted, though, was a way to proactively prevent these attacks—not just identify and control them.

iThemes Security

Right around the same time as the Heartbleed issue, I started seeing articles and emails about the recent purchase of Better Security Pro plugin by the WordPress plugin company, iThemes.

I know the staff at iThemes personally from meeting them at WordCamp Chicago. I’ve also used their BackupBuddy plugin for all my clients since it was released almost five years ago and I’ve always considered it the best WordPress backup or migration tool. Similarly, Better Security Pro was also known as the #1 tool in its market. I considered the two companies coming together a great match.

Respecting a plugin and using it are two different ideas, though. The main reason that I wasn’t already using a more robust security plugin was how complicated and buggy the plugins could be. To effectively secure a site, the plugin was going to have to rewrite files on my server. If something went wrong or if my server configuration wasn’t accounted for, the site might completely shut down.

For years, I had been trying to avoid crashing a site, but with my sites’ security growing ever-necessary by the day, I bit the bullet and installed the newly rebranded iThemes Security—first on my attacked client site and eventually, on every site I maintained.

Even after that first installation, I went really easy on turning on all of the plugin’s options. It wasn’t until I tested out all 30+ tools individually that I finally gave in and let the plugin just run its auto-secure feature. I learned that, surprisingly, you could click one button, and it would take care of 99% of your security needs—and not crash your server, either.

There are still some options that aren’t turned on automatically, but they’re only necessary for the most security-obsessed administrators.

Trust me, though—these esoteric options are great for sites like my client’s that are facing years of brute force attacks. I won’t tell you exactly what I did, but one change in particular has finally eliminated most of my brute force attacks—exactly the result I was looking for.

Since iThemes Security also locked out multiple invalid login attempts (as well as sent notification emails), I was also able to deactivate the Limit Login Attempts plugin. There was no reason to operate both simultaneously.

Step 3: Manage the Sites

Now that the sites were secure, I needed a way to keep them that way.

There are two basic ways to keep your sites synced: either you can use WordPress’s built-in multisite component to install each site in the same database or you can use remote software to display and control your individual WordPress installations.

A year or so ago, I decided WordPress multisite made it too difficult to export sites to other client web servers. This, combined with the fact that some themes weren’t built with multisite in mind (making theme setup difficult), made me switch to using one-off WordPress installations for each of my projects.

Whether this choice is best is debatable. At least with remote software like WPRemote, ManageWP, and now, iThemes own Sync, I still have the ability to log into one dashboard and update all my WordPress themes, plugins and even core. These updates can be individualized or made simultaneously across all my WordPress installations with just a few clicks.

Keeping all my software updated is the best way to prevent any one site from becoming vulnerable and allowing access to the other installations or databases.

Bonus Step: Finding a More Secure Web Host

I’ve recently started using WPEngine for some projects. Compared to my regular shared hosting, WPEngine isn’t cheap, but it does provide incredible peace of mind.

If purchased individually, WPEngine hosting costs $29 per month per site. For less than $30, you’re receiving daily backup points, secure login and file transfer, along with a staging area for every site.

The staging area is an on-demand, instant replicate of your live site where you can make as many changes as you want without breaking your live site. Once you’re happy with the changes, you can even deploy your staging site to live mode so your changes become permanent.

WPEngine isn’t necessary for every website, but it’s certainly more secure.

Besides security, the service also offers outstanding uptime, rapid customer support, automatic file scanning and blazing-fast webpage delivery. That covers almost everything you’d need to offer an enterprise-level WordPress hosting service—the level that I’d like to one day promise (and charge for) all my clients, too.

Migrating sites from one web server to another takes time and patience, though.

As of now, I consider migrating to WPEngine an ongoing project. Eventually, though, I think I’d like to use the service for every site I maintain. Once the migration is complete, I’ll finally be able to stop worrying about being hacked and focus exclusively on building sites that convert visitors into customers—the service my clients need most.

«