Skip to the announcement …
One of the earliest conversations I had in the WordPress community almost saw me immediately leave and never return. I’d released some code in a few plugins and was just finally starting to get ramped up as a (very sub-par) developer. I hung around on IRC, subscribed to the various mailing lists, and tried my hardest to learn, improve, and contribute.
Then someone pointed out that I’d never internationalized my plugins. Then they proceeded to go on a rant about how any developer who
didn’t internationalize their UI was doing a disservice to the community and was betraying their personal bias against and hatred towards non-English speakers.
I was horrified.
I came to the development world from marketing. I used Windows. I was very comfortable with graphical (often skeuomorphic) interfaces and could work my way around things easily with a mouse. I didn’t understand the command line. I
barely understood code. It took me months (and several misfires) just to learn enough Subversion to get my plugins out in the first place.
All of the tools for internationalizing a plugin were, at the time, heavy into a command line that I didn’t understand and couldn’t use.
I took a break and, ironically, this experience is what started me blogging. My break let me get some distance and gave me the chance to connect with other developers who
did understand the command line tools. They taught me things I didn’t know and I came back a much stronger dev.
One of
my most popular blog posts today is an old introduction I wrote for developers who wanted to use GUI tools to publish a WordPress plugin. Honestly, though, I wrote the walk through more to remind myself how to do things than anyone else … and that’s how I got started with most of my blogging work.
A topic I’ve focused on more recently has been cryptography. More specifically, using cryptographic tools to ensure the integrity of various packages and messages. It’s a heady topic, and a lot of the tools available for end users are painfully focused on power users who fully understand command line utilities.
I want to change this.
Code Signing
There’s been a lot of talk about the security of the WordPress updater. Primarily, the updater checks the MD5 hash of a package’s contents before proceeding to ensure its integrity, but that’s the
only test it runs.
Consider what might happen if a malicious party were able to somehow breach the WordPress.org update server and present their own download package. This could potentially inject malicious code onto more than a quarter of the Internet all at once! Considering such a breach has happened with a few plugins in the past, it’s not outside the realm of possibility.
Now imagine if a hacker were able to drop themselves somehow between your server and the WordPress.org update system. Such an attacker could impersonate the updater and serve you whatever package they want. Your system wouldn’t know the difference.
In the middle of last year, I said I was working on a solution to bring formal code signing to WordPress. I held off for a while because it looked like the WordPress community might bring this feature to core.
That didn’t happen.
So today, I’m proud to announce the release of
DGXPCO: Digital Guarantees for eXplicitly Permitted Core Operations. This plugin integrates directly with the WordPress core updater and
requires that any core package have a valid signature in order for installation.
For the moment, I am personally signing the contents of every core package distribution and maintaining the collection of signatures
in a separate repository that I serve through a secure CDN powered by Amazon Web Services.
Every WordPress release includes both the core download for
new installations as well as “partial” upgrade packages for anyone coming from an older install. I’m signing
all of these and keeping a record in one spot so that everything from new installs to partial minor updates to major updates can benefit from the added security of checking a signature.
The signatures are leverage an Ed25519 public/private keypair and
Libsodium to sign the files’ contents. I keep the
private key offline, but have published the
public key so everyone can keep an eye on things.
This key will not change, and if anything is signed by a different key, you can be sure something is amiss.
That public key, encoded in Hex, is
5d4c696e571307b4a47626ae0bf9a7a229403c46657b4a9e832fee47e253bc5b.
Every commit to the release hashes repository is also signed with
my personal PGP key so you can verify that I’m the one who added the new code.
Next Steps
Is this fool-proof? Probably not. It is, however, a huge step forward in terms of WordPress security. There’s quite a bit more we can do, and I want to outline some of my grand plan here.
The first release of the plugin checks signatures upon update only, but WordPress will still tell you about an update even if the signature check fails.
The next release will not even surface an update unless a signature is available.
At the moment, this plugin only secures WordPress core updates.
A future release will also secure plugin updates as well, in an opt-in fashion. I’ll start by securing
my own plugins as a proof of concept, then allow for other developers to opt-in to the stronger security moving forward.
Today, I am the only one allowed to sign release packages. This is OK for the short term, but is not a sustainable model.
As I prove out the update system, I’ll also begin adding sets of public keys that are scoped to specific sets of packages. This will, for example, allow me to whitelist a small number of trusted developers to also sign core packages. It might also empower plugin developers to sign their own releases (but not anyone else’s).
At the end of the day, I’m looking now for feedback. We don’t have this functionality in WordPress core
yet, but DGXPCO is evidence that we can add it. We should add it. So let’s work on the feature together.
As I mentioned in my initial post last year, if you want to help with this endeavor, please let me know! If you want to contribute financially,
donations are always gladly accepted.
This is the
first project I’m launching under the name of my new WordPress-related business,
Displace Technologies, LLC.