Semantically Secure<p>As I write this, the most recent big move by Matt Mullenweg in his ongoing dispute with WP Engine was to <a href="https://anderegg.ca/2024/10/13/acf-has-been-hijacked" rel="nofollow noopener noreferrer" target="_blank">abuse his position to seize control of a WP Engine owned plugin</a>, justifying this act with <a href="https://wordpress.org/news/2024/10/secure-custom-fields/" rel="nofollow noopener noreferrer" target="_blank">a security fix</a>. This justification might, under other circumstances, be believable. For example, if WP Engine <a href="https://www.advancedcustomfields.com/blog/acf-6-3-8-security-release/" rel="nofollow noopener noreferrer" target="_blank">weren’t actively releasing security fixes</a>.</p><p>Now, as I wrote on <a href="https://news.ycombinator.com/item?id=41825692" rel="nofollow noopener noreferrer" target="_blank">a Hacker News thread</a>, I’d been staying out of this drama. It wasn’t my fight, I wasn’t deeply familiar with the lore of the players involved, etc.</p><p><strong>BUT!</strong> This specific tactic that Mullenweg employed happens to step on the toes of <a href="https://ma.ttias.be/wordpress-get-secure-cryptographic-updates/" rel="nofollow noopener noreferrer" target="_blank">some underappreciated work I had done from 2016 to 2019 to try to mitigate supply chain attacks against WordPress</a>. Thus, my HN comment about it.</p><p>Mullenweg’s behavior also calls into question the trustworthiness of WordPress not just as a hosting platform (WP.com, which hosts this website), but also the open source community (WP.org).</p><p>The vulnerability here is best demonstrated <a href="https://xoxo.zone/@lazerwalker/113297704893474421" rel="nofollow noopener noreferrer" target="_blank">in the form of a shitpost</a>:</p>“Matt” here is Mullenweg.<p>I do not have a crystal ball that tells me the future, so whatever happens next is uncertain and entirely determined by the will of the WordPress community.</p><p>Even before I decided it was appropriate to chime in on this topic, or had really even paid attention to it, I had been hearing rumors of a hard-fork. And that maybe the right answer, but it could be excruciating for WordPress users if that happens.</p><p>Regardless of whether a hard-fork happens (or the WordPress community shifts sufficient power away from Mullenweg and Automattic), this vulnerability cannot continue if WordPress is to continue to be a trustworthy open source project.</p><p>Since this is a cryptography-focused blog, I’d like to examine ways that the WordPress community could build governance mechanisms to mitigate the risk of one man’s ego.</p><p><strong>Revisit Code-Signing</strong></p><p>The core code, as well as any plugins and themes, should be signed by a secret key controlled by the developer that publishes said code. There should be a secure public key infrastructure for ensuring that it’s difficult for the infrastructure operators to surreptitiously replace a package or public key without possessing one of those secret keys.</p><p>I had previously begun work on <a href="https://core.trac.wordpress.org/ticket/49200" rel="nofollow noopener noreferrer" target="_blank">a proposal to solve this problem</a> for the PHP community, and in turn, WordPress. However, my solution (called <a href="https://core.trac.wordpress.org/ticket/49200" rel="nofollow noopener noreferrer" target="_blank">Gossamer</a>) wasn’t designed with GDPR (specifically, the Right to be Forgotten) in mind.</p><p>Today, I’m aware of <a href="https://sigstore.dev" rel="nofollow noopener noreferrer" target="_blank">SigStore</a>, which has gotten a lot of traction with other programming language ecosystems.</p><p>Additionally, there is <a href="https://github.com/fedi-e2ee/public-key-directory-specification" rel="nofollow noopener noreferrer" target="_blank">an ongoing proposal for an authority-free PKI for the Fediverse</a> that appears to take GDPR into consideration (though that’s more of an analysis for lawyers than cryptography experts to debate).</p><p>I think, at the intersection of both systems, there is a way to build a secure PKI where the developer maintains the keys as part of the normal course of operation.</p><p><strong>Break-Glass Security with FROST</strong></p><p>However, even with code-signing where the developers own their own keys, there is always a risk of a developer going rogue, or getting totally owned up.</p><p>Ideally, we’d want to mitigate that risk <strong>without</strong> reintroducing the single point of vulnerability that exists today. And we’d want to do it without a ton of protocol complexity visible to users (above what they’d already need to accept to have secure code signing in place).</p><p>Fortunately, cryptographers already built the tool we would need: <strong>Threshold Signatures</strong>.</p><p>From <a href="https://datatracker.ietf.org/doc/rfc9591/" rel="nofollow noopener noreferrer" target="_blank">RFC 9591</a>, we could use FROST(Ed25519, SHA-512) to require a threshold quorum (say, 3) of high-trust entities (for which there would be, for example, 5) to share a piece of an Ed25519 secret key. Cryptographers often call these t-of-N (in this example, 3-of-5) thresholds. The specific values for t and N vary a lot for different threat models.</p><p>When a quorum of entities do coordinate, they can produce a signature for a valid protocol message to revoke a developer’s access to the system, thus allowing a hostile takeover. However, it’s not possible for them to coordinate without their activity being publicly visible to the entire community.</p><p>The best part about FROST(Ed25519, SHA-512) is that it doesn’t require any code changes for signature verification. It spits out a valid Ed25519 signature, which you can check with just libsodium (or <a href="https://github.com/paragonie/sodium_compat" rel="nofollow noopener noreferrer" target="_blank">sodium_compat</a>).</p><p><strong>Closing Thoughts</strong></p><p>If your threat model doesn’t include leadership’s inflated ego, or the corruption of social, political, and economic power, you aren’t building trustworthy software.</p><p>Promises and intentions don’t matter here. Mechanisms do.</p><p>Whatever the WordPress community decides is their best move forward (hard forks are the nuclear option, naturally), the end result cannot be replacing one tyrant with another.</p><p>The root cause isn’t that Mullenweg is particularly evil, it’s that <a href="https://w3techs.com/technologies/overview/content_management" rel="nofollow noopener noreferrer" target="_blank">a large chunk of websites</a> are beholden to only his whims (whether they realized it or not).</p><p>One can only make decisions that affects millions of lives and thousands of employees (though <a href="https://ma.tt/2024/10/alignment/" rel="nofollow noopener noreferrer" target="_blank">significantly fewer today than when this drama began</a>) for so long before an outcome like this occurs.</p>Edit of <a href="https://xkcd.com/2347/" rel="nofollow noopener noreferrer" target="_blank">XKCD</a><p>If you aren’t immune to propaganda, you aren’t immune to the corruption of power, either.</p><p>But if you architect your systems (governance and technological) to not place all this power solely in the hands of one unelected nerd, you mitigate the risk by design. </p><p>(Yes, you do invite a different set of problems, such as decision paralysis and inertia. But given WordPress’s glacial pace of minimum PHP version bumps over its lifetime, I don’t think that’s actually a new risk.)</p><p>With all that said, whatever the WordPress community decides is best for them, I’m here to help.</p><p><a href="https://scottarc.blog/2024/10/14/trust-rules-everything-around-me/" class="" rel="nofollow noopener noreferrer" target="_blank">https://scottarc.blog/2024/10/14/trust-rules-everything-around-me/</a></p><p><a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/advanced-custom-fields/" target="_blank">#AdvancedCustomFields</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/arrogance/" target="_blank">#arrogance</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/automatic-updates/" target="_blank">#automaticUpdates</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/automattic/" target="_blank">#Automattic</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/code-signing/" target="_blank">#codeSigning</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/cybersecurity/" target="_blank">#cybersecurity</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/ego/" target="_blank">#ego</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/matt-mullenweg/" target="_blank">#MattMullenweg</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/news/" target="_blank">#news</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/pki/" target="_blank">#PKI</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/plugin-security/" target="_blank">#pluginSecurity</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/power-corrupts/" target="_blank">#powerCorrupts</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/secure-custom-fields/" target="_blank">#SecureCustomFields</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/security/" target="_blank">#security</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/software-governance/" target="_blank">#softwareGovernance</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/supply-chain/" target="_blank">#supplyChain</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/supply-chain-security/" target="_blank">#supplyChainSecurity</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/supply-chain-security-2/" target="_blank">#supplyChainSecurity</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/technology/" target="_blank">#technology</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/threat-models/" target="_blank">#threatModels</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/trust/" target="_blank">#trust</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/wordpress/" target="_blank">#WordPress</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://scottarc.blog/tag/wp-engine/" target="_blank">#WPEngine</a></p>