Welcome back to our website security series! So far, we’ve seen that all websites are targets, there’s no such thing as perfect security and securing the platform that our websites run on is a 24 x 365 responsibility. From there we looked at the most serious threats to web content management systems and then specific security recommendations for Drupal. Now it’s time to dive deep on WordPress, starting with how to update WordPress securely.
Learn how to achieve secure WordPress hosting with Pantheon.
WordPress’s Release Philosophy
WordPress’s philosophy of frequent releases and backwards compatibility are a significant part of WordPress’s security story. As with many software products, keeping up to date with the latest patches is the most important thing to do for WordPress security. Fortunately, WordPress has made it easy to do just that. Frequent releases means that we all benefit from new features, bug fixes and security patches on a regular basis. Maintaining backwards compatibility between those releases means that your existing themes, plugins and custom code should continue to work as long as they’ve been written well. (More on that later.)
Software updates carry risk, however. We all know that software updates can break things. The WordPress Core team has an incredibly strong commitment to not breaking anything with new WordPress releases. While this isn’t always possible, stories like the following are common:
That worked. I am amazed. @nacin remains infallible!
— Jacob Dubail (@jacobdubail) May 17, 2016
In fact, the famous Trojan Emoji security fix spanned well over a year, even though there was an almost immediate possible fix. That fast fix could—and would—break many sites, however, so it was rejected. Gary Pendergast gave a great talk on this process at WordCamp US in 2015, but the short version is that work continued for over a year to come up with a solution that would work for all sites, even though it didn’t seem possible at times. That’s a serious and commendable dedication to backwards compatibility and not breaking the trust of WordPress users.
Supported = Current
This philosophy of backwards compatibility makes WordPress stand out among its peers. Many modern software applications have moved to becoming constantly updated. WordPress’s combined commitment to backwards compatibility and frequent releases means the only officially supported version of WordPress is the current version. When a security release happens, it’s possible that a previous major release could also be updated, but there are no guarantees.
Knowing that WordPress is kept secure by updating it is one thing. However, staying on top of constant updates is another thing altogether. Fortunately, ever since WordPress 3.7, WordPress has included a background updater that allows you to update your site from the WordPress admin. This is a super convenient feature and it works quite well.
Security Feature or Security Concern?
Somewhat paradoxically, this background updating feature itself introduces a real security concern. In order to work, the background updater requires WordPress to be able to write to itself. As we covered back in Part 1, web content management systems have inherent security risks. Allowing anything connected to the internet to change it’s own programming via the internet is a recipe for trouble. And, in order for background updates to work, WordPress needs to be configured with that power. Unfortunately, this is a very risky setup that can be abused by hackers.
Closing the Gap
The updater can also break some best practices in web development, like version control and controlled deployments. Knowing this, Andrew Nacin, the release lead for WordPress 3.7, came out with a post describing how to disable auto-updates. In it, he articulates three good scenarios for doing so:
You manage your site using version control
You implement your own deployment mechanism (potentially to multiple servers)
You are a managed WordPress host and feel confident in pushing timely updates yourself
If you do not have any of these three situations, do not disable auto updates. If you do have any of these three scenarios, however, there are some additional steps to follow. And, if you happen to use Pantheon, you benefit from all three.
[Related] Pantheon Website Security Services
Updates PLUS Version Control and Controlled Deployments
Hopefully most of us reading this are using version control and controlled deployments for all of our sites. We built this into Pantheon, but it’s not something we invented—it’s a general software best practice. If this is new to you, we provide some training wheels to help you get started using Git with Pantheon, but for the rest of this article I’ll assume that we’re all doing the right thing and using a VCS system like Git and managing our deployments with tools.
Disable File Edits
We don’t want a hacker to be able to gain access to a live site and run arbitrary code. Disabling this functionality is easy—it just requires this snippet of code in wp-config.php:
Disable Updates on Test and Live
Similarly, code should never be pushed directly to a live site. Updates should to be done in a development environment and moved to a test environment when they’re ready for review by humans and/or by running automated tests. Once those tests have passed, code can be pushed to the live production site. Once again, there is a setting for this: define( 'DISALLOW_FILE_MODS', true );, and again, all of this setup and workflow is built into Pantheon. This is what it looks like in our default wp-config.php:
// FS writes aren't permitted in test or live, so we should let WordPress know to disable relevant UI
if ( in_array( $_ENV['PANTHEON_ENVIRONMENT'], array( 'test', 'live' ) ) && ! defined( 'DISALLOW_FILE_MODS' ) ) :
define( 'DISALLOW_FILE_MODS', true );
Build Your Update Process
Now that your site is secured, you need to get your update channel working. Disabling updates is only a good idea if you have your own process to keep WordPress updated. There are a number of viable strategies to do so, each with varying degrees of complexity.
Update Code, Deploy to Test, Review, Deploy to Live
This is straightforward and works well when you only have a few sites to manage. In its simplest form, it looks something like the following:
Login to your WordPress admin in a development or disposable environment (On Pantheon, Multidev is a great place for this).
Update WordPress core, themes and/or plugins as needed.
Spot check your site to make sure nothing has broken.
If all looks good, commit your code changes.
If not, start troubleshooting. You may also need to undo changes by restoring from a backup. If you have disposable environments, you might want to dispose of it and start over.
Deploy code up to Test and sync the Live content and settings down to Test. (This is also built into Pantheon).
Test the site thoroughly. This is your future Live site. Your actual content and configuration is mixing with your new code. Does it all work as expected?
If all looks good, push your code Live.
If not, sync back to Dev and start troubleshooting.
This is arguably the simplest implementation of a basic best practice process. It’s easy to set up, and it’s easy to maintain—especially on Pantheon. The major downside is that it requires human monitoring and action. I personally use this workflow on some my own sites and it works just fine.
Updating Many Sites from One Base
For organizations that support many sites, doing this for each site can turn into quite the chore. Fortunately, most organizations that do this have established a shared codebase used on most of their sites. That codebase typically includes favored plugins, custom plugins, a base theme, etc. The goal with this setup is to be able to update that shared codebase and then have all of the sites based on that site receive the updates automatically. On Pantheon, we call this sort of setup a Custom Upstream and because we’re smart people, we built Custom Upstreams into the platform.
If you don’t have something like Custom Upstreams you can use to manage many sites, you should probably look into a paid service that can help you manage many sites. There are quite a few out there—AskWPGirl has a nice rundown of many of the more popular options.
While custom upstreams and a shared codebase will help, adding automation and scripting to the mix will get you even further. The ideal system would detect available updates, deploy them to a testing environment, test them, and give a report back to a human indicating that the site has updates ready to go. Depending on how good your test coverage is, you might even consider pushing your code all the way out to Live. That would require supreme confidence in your tests as well as knowing that your Test environment is a perfect match for Live.
Once again, Pantheon is the ideal platform for this setup. While it requires some upfront work from you to set up, the basic ingredients are ready for you to work with. Our Terminus command line tool allows you to manage everything you can do in our administrative interface by script. Pair it with WP-CLI—which we’ve done—and add in our Quicksilver hooks to trigger testing and you’re on your way to a truly powerful combination of best practices AND convenience. Pixotech has a nice writeup on their process that does just this and our own Andrew Taylor has a fantastic script for doing all of this plus visual regression testing on Pantheon.
Updating WordPress Securely: Putting It All Together
The first and most important step to securing WordPress is having a rock-solid update strategy. If you’re not using version control and controlled deployments, you should be using the WordPress Background Updater to keep your site updated. If you’re doing professional web development with version control and managed deployments, however, you need—and want—a better system. Pushing your updates through Dev-Test-Live environments with version control is the place to start. Leveraging a shared codebase to flow updates through many sites is the next step. Adding automation to the mix makes it all even better.
Next up: we’ll look at plugins you can use to further enhance WordPress security as well as best practices for secure WordPress coding.
Note: This is the sixth post in a series of articles on website security. See the rest:
- Part 1: You Are A Target
- Part 2: Website Security Isn’t Binary
- Part 3: Security in the Platform Layer
- Part 4: The Application Layer
- Part 5: Securing Drupal
- Part 6: Updating WordPress Securely
- Part 7: Administering WordPress