I often get questions about WordPress security and how best to manage WordPress upgrades. These issues are closely related, and I’ve thought about them a good deal over the years (and I’ve been doing this long enough to have experimented with a variety of approaches). These are the approaches I am currently using and recommend for the technically savvy.
First, a high level summary:
- Upgrade immediately. Always. No exceptions.
- Have a development/staging copy of your site to test upgrades on before upgrading your live web site.
- Do check out your copy of WordPress from SVN (use the current branch) on your production web site.
- Do not run a production web site on WordPress SVN trunk.
- Backups are critical (snapshot backups highly recommended); they are your best defense against security issues and upgrade problems.
Ok, now for the detailed discussion…
WordPress security has been a hot-button topic this year. The security vulnerabilities that surfaced in WordPress releases last year were unfortunate, but some were due in part to a systematic approach to try to improve security in WordPress by standardizing how security functions work throughout the code base.
I’ve seen comments that WordPress doesn’t care about security; I think that’s an ignorant statement. The WordPress developers I know care deeply about the quality of WordPress and are constantly working to improve it.
Historical security is not (necessarily) a good indicator of future security.
While I do believe “those that do not learn from history are doomed to repeat it”, I do not believe that you can accurately predict future security concerns based on the security bugs in the past. In Open Source there is the additional issue of new developers bringing new coding styles and blind spots along with their code contributions. Open Source requires everyone to be diligent for security issues. It’s a battle you must always fight, but will never win.
A quick note about the WordPress codebase: it’s important to consider where WordPress came from. The WordPress codebase isn’t architecturally elegant, but it’s improving with every release. The codebase was initially inherited from b2, and certain development approaches and code paths from that code (written back in 2001-2002) are still present today (for compatibility reasons). I’ve been impressed over the last few years how certain backward compatibility features have been maintained while the underlying code has been completely gutted and rewritten. That’s not easy.
I haven’t spoken to anyone on the core dev team about this yet, but I think that the 3.0 release (WP – WPMU merge) is probably the right time to break a few things in favor of consistency for the future. I’m sure that’s a discussion that is already taking place.
Here are some simple tips that may help with security going forward:
- The best way to be hacker-proof is to upgrade immediately and have great backups (more on backups later).
- Turn off features you don’t need or use. This includes user registration, XML-RPC, etc.
- Use only the plugins you need, and consider the source when adding any feature (plugin or theme) to your site.
- Remove plugins and themes that are not active.
- Add 401 authentication to your wp-admin directory.
- Use SSL when connecting to your admin interface.2
New features bring new bugs, and some of those will undoubtedly have security ramifications. The best way to combat this is to upgrade immediately when a new version is available. I upgraded four WordPress installs in three minutes this morning – it’s easy if you set them up right.
The approach I use won’t work for everyone as it relies on developer tools that not all WordPress users are familiar or comfortable with. If Subversion (SVN) is meaningless or scary to you, I recommend sticking with the auto-upgrade or working with someone who can provide the appropriate technical skills to use the approach outlined here (the WordPress HelpCenter is a great option for this).
The WordPress codebase is hosted in a publicly accessible SVN repository – you want to use that. The SVN repository is organized in a traditional manner providing us with a variety of options for what code we want to use.
I recommend checking out the current branch of WordPress and using that for your web site. The benefit of using a branch is that you can simply
svn up to update to the latest patch release. If you replace the plugins and themes directories with your own SVN checkouts (as I do on some sites), you will want to use a more selective command for your update:
svn up *.php wp-admin/ wp-includes/
That will get you all the latest code, without affecting the wp-content directories (plugins and themes). Branches are pretty safe – typically the only changes in a branch are to apply the bug fixes and security patches that comprise the point releases for that branch.
If you want to automate your updates using CRON to pull from SVN, this is the process I recommend.
Some folks advocate using tags (the official WordPress releases) exclusively. There is certainly an argument for this, however the
svn switch command used to change between tags (and branches, for major releases) is not as easy as the update command on a branch (especially if you’re replacing versioned directories like wp-content/plugins and wp-content/themes in your checkout).
I’ve seen other people advocate running on trunk. This is madness! Trunk is where new bugs and security vulnerabilities are written – you do not want to be running trunk. We’ve been having data loss issues1 on an internal site of ours that currently runs on trunk.
I strongly recommend that any upgrade be tested on a development or local environment before performing the upgrade on your live web site. The importance of this varies from site to site, but if you’re running a significant site on WordPress (like some of the ones we’ve built at Crowd Favorite), you can’t afford to have your site down because some change in the new release introduces an incompatibility with your configuration or custom code.
So that takes care of upgrading WordPress, what about plugins and themes? It’s true that some WordPress upgrades will break plugins and themes. However, that doesn’t mean you shouldn’t upgrade. If a plugin or theme breaks, you should contact the developer and see if they plan to upgrade the plugin or theme. If they don’t, you may be able to bribe them. If they still won’t, you can see if someone else will do it, or move on. No plugin or theme is more important than your site’s security.
Having a good, deep knowledge of how WordPress works and interacting with it in the proper way will allow you to write plugins and themes that hum along smoothly after a WordPress upgrade in most instances, but you should still test in a non-critical environment.
It’s important to note the position that plugin and theme developers are in with WordPress upgrades as well. When a plugin or theme breaks in a new version of WordPress, it’s not always the developer’s fault. Sometimes a plugin or theme is poorly written and does not follow WordPress coding standards – sometimes the standards that are to be followed are more recent than the plugin or theme in question. The recent change to how widgets are to be coded is a great example. The best practices are constantly evolving, and it can be a challenge to keep up with them all.
I currently have 28 plugins and 3 themes registered on wordpress.org. When a new version of WordPress is released, it’s a tall order to test and patch all of these. There are typically 4 major WordPress releases scheduled each year.
If I did a full test and patch cycle (1/3 day-1 day each) of every plugin and theme I have released with every major release, I’d be spending 4 months a year just testing and patching my plugins and themes.
That isn’t something I’m in position to do, and other plugin and theme developers are in similar positions (to varying degrees).
Additionally, the plugin and theme system of WordPress is in essence a security feature as well. Because of the ability to customize WordPress without making modifications to the core codebase, you can upgrade without having to go through and apply all of your modifications to the new codebase.
In the event your site is hacked or an upgrade goes south (or really if anything bad happens), your best defense is having great backups.
RSYNC is a great tool, but if you are using RSYNC exclusively for your backups it’s likely you aren’t doing enough. RSYNC will keep a mirror copy of whatever you tell it to back up – this means that if something bad happens on your site, the same thing will be mirrored to your RSYNC backup. There are a bunch of ways to mitigate this – if you are a do-it-yourselfer you are likely already brainstorming a few decent work-arounds. Almost all of these break down if the hack is undetected for a long period of time (a week or two) as staggered RSYNC solutions don’t typically extend that long.
I think the best solution is snapshot backups, going back a reasonable amount of time into the past. This will allow you to pick a known, good point in time to revert to. Test locally, and restore your production site.
During a recent security upgrade rush at WordPress HelpCenter we discovered that many people who thought they had good backups from their hosting providers, didn’t. It’s important that your backups are both monitored and verified for integrity.
Recovery time is important as well. You want a system that allows you (or your recovery team) to get your backups up and running again quickly. Speed is a big issue when your site is down, and having to apply differential backups to do a restore can be very time consuming.
We created BackupMoxie because we needed a service that worked this way for our clients at Crowd Favorite. If you are interested in offering BackupMoxie as a service to your clients, I’ve got good news for you. Next week we are officially launching it as a white label service.
Hopefully this (lengthy) discussion has been helpful for some of you.
In thinking about these issues and in the development my team and I have done over the last few years, I’ve considered a number of ideas that I think could be helpful to the WordPress community. I’m working on an outline for an idea that I think may have some merit for a follow-up post.
- Still need to try to debug them and submit a patch, actually. [back]
- Support for this is relatively recent, not all plugins and themes (including mine) support this properly yet. [back]
This post is part of the project: BackupMoxie. View the project timeline for more context on this post.