I have a confession to make. I really like the new Gutenberg editor for WordPress.
I know, I know. Developers aren't supposed to like massive, intrusive changes like this. As of the time of this writing, the plugin stands with 2.6 stars on the plugin repository – at least 133 of those ratings are 1-star critiques.
As a writer, though, it's an incredibly slick interface.
As a developer, I can also see the promise behind the block structure for taking over the rest of the WordPress admin. The customizer could easily use the block structure for things like widgets and navigation and content layout. Even settings pages could be updated to leverage blocks for different sections.
Also as a developer, I can see why so many are hesitant to dive in with the new system. It still has a few rough edges, but nothing that's impossible to polish as development moves forward. It's also a massive deviation from the interface we're all used to.
The Problems Ahead
Having worked both as a WordPress freelancer and with a larger WordPress agency team I admit this new editor does give me pause. Several of the systems I've built or worked with feature rich, custom interfaces – all built atop the standard WordPress editor screen.
While I plan to leverage Gutenberg's newer interfaces with any project I build atop WordPress 5.0 or later, this isn't a solution for everyone.
Not that long ago, a friend of mine who works with an established non-profit reached out to me for some WordPress help. The team had hired a developer to build out their site, but they'd since parted ways. Unfortunately, the developer had left a large banner on the front-end of the site pointing out the design was new and soliciting user feedback.
The team wanted to turn off the banner, but didn't know how. They also couldn't ask the original developer to take care of it for them.
My point is that many existing WordPress users are working with platforms built by outside parties or powered by themes and plugins that they cannot update on their own for whatever reason. Switching to the Gutenberg editor for posts (and pages and other CPTs) is going to pull the rug out from under a lot of businesses who've grown to trust our product to build their business.
A Potential Solution
Two roads diverged in a yellow wood,The Road Not Taken, Robert Frost
And sorry I could not travel both
And be one traveler, long I stood
And looked down one as far as I could
To where it bent in the undergrowth
About four years ago, I suggested that WordPress should fork itself for the sake of updating its PHP requirements and empowering developers to leverage newer features in their code. Several other developers chimed in and supported the idea, but we didn't tread down that path because, honestly, it wasn't a good fit for the project as a whole.
Now, though, everything is different.
Gutenberg is great, but it's not a good fit for the project as a whole. WordPress is not just a blogging platform. It's not just a tool for the creation of prose. It's a rich content management system with support for both prose and media and, thanks to the power of custom post types, anything else a customer might need.
I strongly believe that Gutenberg, and its block-based approach to building webpages is the way of the future. I strongly believe that Gutenberg should be part of WordPress – perhaps not just a part but should take over the WordPress interface entirely.
I just as strongly believe that the broader WordPress community isn't ready for Gutenberg and won't be for quite some time.
For the time being, I propose that WordPress create a "soft fork" of the project. Maintenance, security, and minor feature improvements should continue on a 4.X branch (with a 4.10 release coming next, followed by 4.11, etc). Gutenberg should (and will) be the default editor with WordPress 5.0, but no one necessarily has to upgrade to the 5.X branch until they're ready for it.
This would give developers the time to upgrade their plugins and themes. It would give users the time to familiarize themselves with the newer interface. It would also allow for faster, broader experimentation with the new block-based approach.
WordPress' overarching development principle has been to always maintain backwards compatibility. It's one of the reasons why we target PHP 5.2 as a minimum. It's one of the reasons why I can click "upgrade" on an older 3.X site and bring it up to speed with 4.9.1 without anything breaking.
It's one of the primary reasons why WordPress has been so successful as a platform.
Unfortunately, Gutenberg is such a deviation from what we've used in the past that it's all but impossible to maintain backwards compatibility without ugly hacks.
- Meta boxes, one of the core ways plugins extend the WordPress admin interface, are included in Gutenberg by way of iFrames. It's a buggy implementation that has many developers arguing over best practices and approach.
- The page editor is missing the concept of "page templates" entirely. Up til now, templates were the key way site owners customized the appearance of their content – this doesn't fit within a Gutenberg model. Leveraging a page template requires deactivating the plugin, selecting the template, then re-activating the plugin to build content.
- Blocks are added to post content using HTML comment tags – the content isn't actually broken up into separate blocks and the blocks themselves don't function as standalone objects. This reminds me too much of media within WordPress, where media items are inserted by way of HTML tags into content rather than as references back to the original media item.
Gutenberg reimagines and reinvents the way WordPress is built. This is a good thing! But we shouldn't be shoehorning the newer features into older structures because we're afraid of breaking backwards compatibility on the back-end. Gutenberg already sacrifices backwards compatibility on the front-end!
A soft fork of WordPress would allow us to:
- Update the database to better house blocks as objects that can be reused and references across content
- Reimagine the media library as a catalog of reusable media blocks
- Update other components of the WordPress admin to leverage blocks (a "settings" block perhaps?)
All of this would be possible without breaking the functionality of highly customized sites if they remained on the 4.X branch. They'd still get security updates, maybe performance updates, and possibly even minor, non-Gutenberg-related feature updates moving forward.
Maintaining both the 4.X and 5.X branches in parallel would also provide developers (both on the larger agency and smaller freelance side) the ability to seamlessly upgrade from a legacy to a Gutenberg environment.
Soft-forking isn't unheard of. Microsoft followed this pattern when they replaced Internet Explorer with IE Edge. Firefox did it with the new Firefox Quantum.
Gutenberg is the road ahead for WordPress. It's a road I want us to take. But it's a road that not everyone will be willing to tread. We should respect that and plan a way to help those who can't follow to keep up.
WordPress powers over a quarter of the Internet. That’s quite a statement for a platform that began its life as a fork of a blogging engine. It’s also quite refreshing since WordPress is the reason I learned to write code in the first place.
One of the reasons WordPress is so popular is because it’s so easy. It’s easy to use as a writer. It’s easy to manage as a site administrator. It’s easy to code as a developer. This learning curve associated with WordPress is relatively flat – many devs and users can dive right in and get something functional from day 1 with little to no outside help.
Another reason for WordPress’ popularity is its long memory. WordPress has been around for over a decade, and the core development team has always prioritized backwards compatibility with the platform. Users of older versions of the software can upgrade to the latest version with, often, no loss in functionality. 1
Unfortunately, this long tenure also means that many in the community have a long memory of WordPress as well. They remember the days before plugins. The days before CSRF tokens were in common use throughout the codebase. The days when everyone just assumed WordPress was insecure by default.
Is WordPress Insecure?
Along a similar vein, WordPress is still very insecure.
At conferences I often remind people that the core code that powers WordPress is, in itself, vetted, secure, and reliable. The insecurities in code arise when administrators add a custom theme or start installing unverified third-party plugins. Any time you add someone else’s code to the system, you add a potential inroad for code-level vulnerabilities.
Among the various risks presented by WordPress, there are four in particular that I see most often in conversation:
A few versions back, WordPress removed the default “admin” username and started enforcing stronger passwords for authentication. These are both good changes to make, but don’t necessarily take things far enough. WordPress does not ship with a multi-factor authentication system. The core team has been working to build one; unfortunately the current solution bundles so many potential options as to paralyze site administrators. They can choose anything from FIDO U2F to Google Authenticator to an email-based system.
It’s a good start, and will definitely help secure WordPress logins, but it’s bringing too many options to the table.
If you forget your WordPress password, you can easily request a reset link from your site by providing either your username or your email address. The downside with this functionality is that anyone with access to your inbox can then use this link to reset your account.
You use a different password for Gmail and for your blog? Great! Unless someone steals your Gmail password … then they can also steal access to your WordPress account.
Many WordPress sites are rocking HTTPS thanks to Let’s Encrypt and the awesome integrations managed WordPress hosts are forming with the project. Sadly, just as many sites are failing to prevent mixed content or are trusting the scripts on their site to CDNs or other remote providers who may or may not be injecting malicious code. The sheer number of people who recommend using a CDN-hosted jQuery versus the version that ships with WordPress 3 shows how often developers are lead to trust an outside party to load executable code onto their site.
WordPress ships all updates (core, themes, and plugins) from a central server, but does nothing to ensure the integrity of the code downloaded. On the one hand, if the central WordPress.org server distributing updates were ever breached, more than a quarter of the Internet would be vulnerable to malicious software.
On the other hand, if your server is behind any sort of proxy and that proxy is attacked, whether or not WordPress.org is shipping rock-solid code becomes a moot point. There’s still no way for you to verify the proxy didn’t modify the payload before you received it. 4
Changing the Conversation
I’m tired of people lamenting the state of security with WordPress and doing nothing to address it. To be certain, there have been some significant efforts to address these security risks, but they either haven’t landed or have been de-prioritized to the point of obscurity. That’s a major disappointment, but I’m not going to just sit back and do nothing.
Instead, I’m going to open source the solutions I’m personally building to help fix the holes and turn the conversation around.
I continuously beta test various login security plugins to see how they can help average users stay more secure. The Two Factor plugin the core team is kicking around is great for people who know what they’re doing and want multiple options for authentication. I like it because I can use it with a Yubikey. I don’t like it because most users don’t even know what a Yubikey is.
I started with that plugin as a core, but reworked it to focus just on using a time-based OTP app and released a simplified fork named Dovedi. This plugin uses a lot of the same techniques, but is tested to work with everything from Google Authenticator on Android to Windows Authenticator on Windows Phone. 5 I wanted to target technology many users already have – even if they’re not already using an Authenticator app, it’s something portable enough they can use it with other systems as well.
Dovedi was my first step in helping to make WordPress secure.
I’ve written extensively elsewhere on the need for and ease of configuring encrypted email systems. I use both GPG and S/MIME myself to ensure messages are signed whenever I send them and encrypted when they need to be. Once you have an email client capable of receiving and decrypting messages, the next trick is getting WordPress to send encrypted messages.
This past weekend, I released a new plugin called Secure Messaging that uses GPG to automatically encrypt password reset emails before they’re sent to a user for reclaiming their account. Once you’ve given WordPress your GPG public key, no one but you (with your private key) can ever steal your account, even if they somehow manage to hack your inbox.
One of the coolest tools I’ve seen lately is Mozilla’s Observatory. This tool scans your site for compliance with many different security features:
- A content security policy that whitelists the domains allowed to serve scripts, images, fonts, and iFrames
- Whether or not your site properly implements HTTPS and if it strictly prevents TLS downgrade
- Whether or not your site implements sub-resource integrity for remote scripts
- If your site is protecting against cross-site scripting or frame-injection attacks
- And so on
By default, it’s difficult to get WordPress to score well under these tests. 6 I’m collaborating with a couple of other developers to flesh out a plugin that helps configure a WordPress site to score much better according to these scans.
Remember, a higher score means a more secure front-end and a safer experience for your customers.
It doesn’t look like the core team will be cryptographically signing updates or payloads any time soon. That being said, I still want to ensure sites I interact with are receiving vetted, secure code. To that end, I will be publishing a list of signed hashes for core files (and a handful of plugins and themes) myself.
I will also be writing a plugin to force the WordPress updater to verify these hashes before completing the upload.
This obviously won’t fix a hacked site, and it won’t protect against all possible avenues of attack. However, it will help ensure that critical code being download through an automated update (via a proxy, for example) is guaranteed by me to be free from outside manipulation.
Next Step: Profit?
All of this is a labor of love. The tools above are, like almost everything else I do, freely available as open source. Where possible, I license under the terms of the MIT license (but use the GPL on tools like Dovedi, which are forked from others). All of the above constitute a fair amount of work on my part, but my goal is to provide these tools to the community and help change the conversation about WordPress and core security.
The best way to help, though, is to raise awareness and offer feedback. Where are the rough edges in WordPress or in the systems that secure it? What could be done to make the “secure” way to do something the “easiest” way?
- I personally upgraded a WordPress 2.3 site to 4.0 once. For context, version 2.3 came out 7 years before version 4.0. Still, the upgrade went flawlessly with zero lost content. The old theme even still worked on the newer platform! ↩
- I use the term “risk” instead of vulnerability here because each of these potential issues requires specific expertise to exploit. They’re also easy to defend against in a rigorous system. They are still risks, though, because it’s even easier to fall prey to a hack merely by being lazy or misreading a configuration tutorial. ↩
- These two are not equivalent. WordPress enables “no conflict mode” by default by adding a line to their own script! ↩
- For all the talk about why update signing isn’t a priority, the risk of a hacked proxy is significant to anyone running on a managed host, in an enterprise environment, or retrieving data through any sort of cached proxy (or external update system like Packagist). ↩
- The hash spec is implemented roughly the same for both, but Windows requires a longer key than Google does. I needed to increase the byte length of device secrets to gain universal compatibility. ↩
- My “dev journal” on WordPress.com, for example, only scores a D where an A+ is possible. If WordPress.com is the “gold standard” for WordPress hosting, we’ve obviously got a lot of work left to do. This site, hosted on WP Engine at the time of this writing, does even worse with an F. ↩
A story I enjoy retelling is how a friend of mine tricked me into using WordPress. At the time, I was working with him on a career mentorship project. He’d written a book that I was publishing, and we wanted to add a premium video series to go along with it.
We just needed a way to host those videos online.
I was still very new to web development. I had built my own portfolio site in PHP, having learned PHP through a series of emails from a good friend in Arizona. My business partner was excited about the prospect of a dynamic website and turned me loose to find the right tool.
I settled on … not WordPress.
A few days later, he invited me to lunch downtown. Having no real job and, since our project wouldn’t be launched or profitable for a few months, I had no money and was thrilled at the thought of a free lunch. I parked downtown and met at an obscure office building … where the first ever WordCamp Portland was being held.
Spending the day with a bunch of WordPress geeks was fun and excited me about the tool. I switched gears and rebuilt our site on WordPress. I rebuilt my own site on WordPress. I started publishing plugins and a few themes for WordPress. I started contributing code back to WordPress Core.
But I still wasn’t a “WordPress professional.” It was just a hobby.
Software as a Profession
I was active enough in the WordPress community that I could start freelancing and actually earning money with my hobby. I never wanted to be a developer, so it was a bit humbling to admit that I was making more money with my hobby than with my real career in business. That said, I was able to use my WordPress freelancing to build a solid resume and get a job.
Writing code in C#.
I still hacked on WordPress as a freelancer in the evenings and on weekends. I still gave my code away for free, having been inspired by meeting Matt Mullenweg and hearing his mantra of “do your best work, give it away for free, and the universe will provide.” Considering his success, I figured it was good advice and followed suit.
I also kept attending WordCamps and worked my way up to speaking at them. Several people asked me why, despite my passion for open source, I wasn’t working with WordPress professionally. The constant questioning, and direct encouragement from certain individuals I highly respect, lead me to apply to Automattic.
Working with WordPress
I applied to … several positions with Automattic over a period of years. I applied to be a code wrangler. A theme wrangler. A happiness engineer. Whatever position I saw open, I threw my resume at. Every time I got back a “thanks, we’ll be in touch” response.
But that was it.
I have never once actually worked for Automattic. In 2012, I was incredibly excited to accept an offer with 10up where I finally got to work with WordPress full time. I spent four years with that team, building some of the best, most complex WordPress installations on the Internet. I also kept up with my habit of evening and weekend work to help polish and improve the platform upon which we built our products.
That’s also when I noticed a troubling trend …
WordPress is not WordPress
I can already feel the backlash brewing, but there are a lot of problems within the WordPress world. Among the worst of them (from a business perspective) is the WordPress name itself.
“WordPress” is a trademark owned by the WordPress Foundation. Because Matt Mullenweg is the founder of WordPress, the WordPress Foundation, and Automattic, the latter has perpetual and unique permission to use the trademark in ways prohibited to the rest of us. No one else is allowed to:
- Call their product “WordPress ____.” It must be “___ for WordPress” or something similar that explicitly calls it out as an extension.
- Use WordPress in their domain name.
- Use the WordPress name, logo, or in any way suggest an affiliation with a non-GPL licensed work.
One of the consequences of all of the above: Automattic directly and financially benefits from the WordPress name because their flagship product, WordPress.com, is so often confused with it. This is an issue that’s come up time and again, but which Automattic does nothing to combat. In fact, they often encourage it!
It cannot be said enough: WordPress.com and Automattic are not the same thing as WordPress.
The other day, I tweeted my frustration about the ongoing confusion bleeding its way into (and being encouraged by Automattic) radio commercials for the WordPress.com product. A few people challenged me on that, some even going as far as to say it was a good thing. I disagree.
As a volunteer contributor to WordPress, watching a for-profit company benefit directly from my unpaid work is infuriating. Said more eloquently:
The people that work on WordPress put their energy and passion into the project. It’s demoralizing to hear the project referenced as something made by a company you have nothing to do with. (WordPress versus Automattic)
The last time I engaged in this debate was over the mobile apps for WordPress. Again, due to trademark issues and the fact that a business needs to “own” the apps in both the Android and iOS stores, the WordPress mobile apps are listed as being “by Automattic.”
As a past contributor to both, I bristle at the thought of a company with whom I have no affiliation putting their name on my work. As I said at the time, I would have no problems with these apps being “by the WordPress Foundation” or carrying some other affiliation stating they’re community projects and not Automattic products.
I have no problem with Automattic building their business and promoting WordPress.com as a product. It’s solid and solves real needs by consumers.
I have no problem with WordPress.com advertisements on TV or the Radio or elsewhere. They’re great ways for Automattic to build recognition of their product and encourage new signups.
I do have a problem with advertisements conflating WordPress and WordPress.com by subtly suggesting that the “27% of the Internet run on WordPress” is due to Automattic or is somehow because of WordPress.com.
I do have a problem with anyone, organization or individual, claiming to respect and value community contributions or open source who directly uses restrictions like trademarks to financially benefit on the otherwise free donations of that community.
When I began writing code for WordPress projects, I had no idea how to properly internationalize 1 my content, There were a few blog posts at the time that accused developers like me of doing a disservice to our customers.
I took offense at the time, but they had a point.
Internationalization is extraordinarily important for open, distributed systems. It’s a valuable feature of WordPress that helps make the software accessible to millions of non-English-speaking writers around the world. Unfortunately, it’s also a mechanism that’s poorly understood and has been confused with some security features of the software.
Rather than call anyone out for doing something wrong, let me instead explain a common mistake that I have made in the past so you can avoid it in the future.
Anyone working with large computer systems today will explain to you the importance of working with safe versus unsafe data. The data returned by an atomic, deterministic function under your control is safe. Data input by a user or retrieved from a remote data source is unsafe.
Unsafe data must be sanitized before it can be used.
When we’re building WordPress websites, we’re required to take a somewhat pessimistic view of our own data sources. While we make every effort to ensure no nefarious data is ever stored in the database, the fact remains that it’s still not entirely within our control. As a result, we must also escape this data upon output to the web browser.
In WordPress, we use a set of specialized functions to do this:
- esc_html() for arbitraty data that may contain HTML
- esc_attr() for HTML attributes
- esc_url() for URLs
- esc_textarea() for arbitrary data targeted for entry into a textbox
The downside is that some of these functions look deceptively similar to some other, internationalization-specific, ones.
While there are far more than just two, the two most common translation functions you’ll see in a plugin, theme, or in WordPress itself are __() and _e(). The first is meant to return a translated string while the latter is meant to echo the translated string to the browser.
Luckily, WordPress exposes a set of functions to do just that:
Considering what we know about the escaping functions above and the new translation functions just mentioned, it should be fairly obvious what these are and how they’re meant to be used.
`esc_attr_e()` is not a shortcut for `echo esc_attr()` and we shouldn't use it as such.
— george ﬆephanis (@daljo628) March 29, 2016
Unfortunately, it’s fairly easy to assume that things like esc_html_e() are aliases for things like echo esc_html().
They’re not and should not ever be used as such.
In reality, esc_html_e() is an alias for echo esc_html( __() ). If used to escape and echo arbitrary (not translated) text, it will still pass the content through WordPress’ translation mechanisms. It isn’t quite apparent from the seemingly short function names for these internationalization functions, but translation mechanisms are among the most expensive operations that run in WordPress.
In other words: using a translation function on content not meant to be translated is a massive performance sink for your site.
If you’re using these functions incorrectly, don’t be discouraged. It means you were on the right track and are far ahead of many other developers; you just need to take one more, minor, jump to use the functions correctly.
- Internationalization (sometimes shortened to I18N) is the practice of marking strings in one language as translatable to other languages and helping to enable the translation. ↩
Yesterday, someone made the argument that the WordPress Foundation’s stance on the GPL helped demonstrate the spirit of WordPress’ mission to democratize publishing.
If you go after a split license, which legally still puts you in compliance with the GPL, you will not necessarily be welcomed with open arms into Foundation-driven events like WordCamps.
The Foundation only chooses to endorse fully-GPL products and businesses. While you’re still welcome to attend, you can’t speak, sponsor, or organize an event because that level of participation would be seen as endorsement by the Foundation.
The idea behind WordPress is to democratize publishing and make it available to everybody … Everyone gives the Foundation a lot of grief for enforcing those rules and what not, but it’s important that we maintain that spirit. As WordPress continues to become more mainstream, the spirit of WordPress can become diluted.
I’ve always agreed that WordPress has been focused on and is making great headway in democratizing publishing. But given the context of the above, I’m not so sure these kinds of behaviors are necessarily in-line with the “spirit” of democratization in any market.
WordPress and Democratization
The WordPress community has many different facets; it would be folly for me to address each, or even every dimension of just a few. Instead, let’s focus on just a handful of elements of a handful of the pieces that make up this thing we call “community.”
First is core development. While we say WordPress’ mission is democratization, there is no where that rings less true than core development. The core team is not a democracy. It’s a meritocracy.
These are two very different forms of governance. In a democracy, the most popular ideas win out. There’s often a vote. The leaders of the community change somewhat frequently as the direction of the community changes.
In a meritocracy, power is held by a smaller set of individuals who have earned their voice and way in to the inner circle directly through the merits of their contributions. The most popular ideas don’t always win. There’s rarely, if ever, a vote. The leaders of the community are a pretty steady list of names.
This is not a bad thing.
This is the way things are done in the WordPress world and is the primary reason the software has achieved so much success. The leaders of the core team are incredibly passionate about their work and do an outstanding job at guiding the rest of us to build a cohesive, robust, consistent product.
It’s also a key example of how WordPress does not embrace the spirit of democratization.
If anyone thinks hard enough, they can come up with an example or two of a way events in our community have dredged up ire against the WordPress Foundation. I’ve been around long enough to remember the days before the WordPress Foundation, and can tell you from experience that events in our space were very different.
The Foundation was established primarily to protect the WordPress (and others) trademark. Its duties have expanded to helping shepherd various WordCamps and WordPress meetups. These are often very complicated endeavors, so the assistance and experience the Foundation lends are invaluable to organization efforts.
They also cause significant problems.
Once, while moderating videos for WordPress.tv, I came across a fantastic video of a developer explaining resources for newer contributors to get involved. Among books and blogs and podcasts, he mentioned a few websites budding developers could turn to for inspiration. One of which was a theme marketplace that, until recently, was considered taboo in our community because they allowed for split licensing.
The less-than-a-second mention of just one potential resource among many led to his video being blocked on WordPress.tv, lest someone accuse the Foundation of endorsing said marketplace by allowing the split-second statement in a 45-minute video to air.
Add in the kerfuffles we’ve had with organizing larger events like
WP Weekend Phoenix WordCamp Phoenix, and you’ll see a trend of the Foundation policing not just the events we can hold within the community, but the content we can exchange at those events.
Unfortunately, like the core development team, the WordPress Foundation is not a democracy. It’s a foundation established by an individual that currently has a handful of employees, does not conduct votes, and does not change leadership when the sentiments of the community it represents change.
Another example of how WordPress does not embrace the spirit of democratization.
My goal is not to sling mud on the core team or on the WordPress Foundation. As I said above, both groups are doing an incredible job standing up for and helping to further the vision of WordPress.
My goal is to point out that, as much as we say the aim of WordPress is democratization, everything we do within the community says the opposite. Actions speak louder than words, and no amount of screaming will hide the meritocracy of contribution or the bureaucracy of the Foundation.
Nor will it silence the way plugins, themes, and contributors in general are denied participation in community properties like WordPress.org unless they follow “the WordPress way.”
Do I believe in the idea of democratizing software and publishing? Absolutely. Does WordPress have a role to play in furthering both? Absolutely.
Does WordPress – and the community around it – really embrace a spirit of democratization? Let’s see if we can answer this question in 2015.