[wp-trac] [WordPress Trac] #39309: Secure WordPress Against Infrastructure Attacks
WordPress Trac
noreply at wordpress.org
Wed Jul 10 08:09:21 UTC 2019
#39309: Secure WordPress Against Infrastructure Attacks
------------------------------------------+---------------------
Reporter: paragoninitiativeenterprises | Owner: pento
Type: task (blessed) | Status: closed
Priority: normal | Milestone: 5.2
Component: Upgrade/Install | Version: 4.8
Severity: critical | Resolution: fixed
Keywords: has-patch | Focuses:
------------------------------------------+---------------------
Comment (by paragoninitiativeenterprises):
@dd32 It sounds like we're on the verge of reinventing X.509.
Please beware that every library that provides X.509 also drags you into
backwards compatibility hell (see: 1024-bit RSA signatures, PKCS1v1.5,
SHA1, etc.) and is generally a mess of ugly code. (ASN.1 parsers, basic
constraints enforcement, etc. also add to the complexity a whole lot.)
I certainly wouldn't feel comfortable recommending that for WordPress to
adopt and maintain.
Our company has been working on a saner alternative, designed specifically
for the "software update" use-case. It's not a "kitchen sink" protocol
like X.509 (and would never be suitable for replacing certificate
authorities in the TLS ecosystem), but much more narrow in scope.
We mentioned it in [https://paragonie.com/blog/2019/05/wordpress-5-2
-mitigating-supply-chain-attacks-against-33-internet|our blog post], under
the name Gossamer. It's not ready for prime time yet, but it's exactly
what @pento was hoping exists.
> Ideally, there would be package signing libraries that would handle a
lot of the process around this, particularly with regards to key expiry
dates, forcing early expiration, and trusting key chains. (Is anyone aware
of such a library we could use?)
Since there's immediate interest in this topic, let me spoil the surprise
and explain how Gossamer works.
== Project Gossamer - Update Transparency and Developer Freedom
In simplest terms, Gossamer exploits two properties of a cryptographic
ledger (1. being append-only, 2. decentralized verification) to build a
public key infrastructure that doesn't require privileged single points of
failure (i.e. Certificate Authorities in X.509).
First, we need to decide on a ledger. Google's
[https://github.com/google/trillian Trillian] is an adequate choice, but
[https://github.com/paragonie/chronicle Chronicle] is the one I used in
the security proof I'm writing. We can have a separate discussion about
that design decision; it's probably a bit out of scope for this ticket in
particular.
The security properties of the two designs are comparable, and the nuances
of their differences are only of interest to academic cryptographers and
security researchers. Naturally, they should absolutely be discussed
before any implementation is adopted, but they provide the same security
guarantees we need, and that's all that matters for the sake of
understanding Gossamer's design today.
Next, we simply need to write all of the following to the ledger:
1. Some metadata (including SHA384 checksums and signatures) about each
software update (including core updates, theme updates, and plugin
updates).
2. New public keys, tied to a specific vendor accounts.
3. Public key revocations and/or replacements (which may be signed by a
public key associated with the vendor OR by the WordPress core, for
emergency situations).
4. Release revocations (i.e. in the event of a malicious update).
Using all of this, we can deterministically build the current state of
affairs for which keys are currently trusted, what their capabilities are,
and what they have been used for, all in an append-only verifiable data
structure.
This isn't just a theoretical discussion, we've actually implemented it
already. [https://github.com/paragonie/herd HERD] is a PHP library that
reads a Chronicle instance and achieves the desired properties. **Note:**
HERD is very generalized and configurable; if implemented in WordPress, it
would be far more opinionated.
=== What Gossamer for WordPress Would Look Like
There would need to be a Trillian or Chronicle instance somewhere in the
WordPress ecosystem. Large hosting providers would greatly benefit from
running a replica instance and configuring their customers' WordPress
sites to query the host's instance rather than the central one. Ideally,
we'd also have multiple public replica instances to keep the load
distributed.
Plugin/theme developers would need tooling to generate/manage their
signing keys. These can range from very primitive shell scripts all the
way to full-featured IDE integrations with cloud backups protected by
authenticated key exchanges and AEAD encryption modes.
The infrastructure in place would need a minor code change to push new
software updates to the Chronicle instance that the other replicas read
from (e.g. with [https://github.com/paragonie/quill Quill] or an
appropriate library). Additionally, when a developer adds/removes a public
key, or an update is pulled because it was found to be malicious, it would
also be written to the ledger.
WordPress core would need a mechanism for either:
1. Storing and parsing the replicated Chronicle data locally (i.e. for
self-hosters and at-risk populations with a scarier threat model than most
bloggers).
2. Offloading their trust to another application (this will likely be
popular for hosting providers).
However it ends up being configured, the API needs to be simple:
{{{
/**
* @param string $vendorName
* @return array<int, array<string, string>>
*/
wp_get_vendor_public_keys($vendorName) { /* ... */ }
}}}
This will retrieve all of the currently-trusted public keys for a given
vendor.
{{{
[
{
"type": "ed25519",
"public-key": "foobaretcbase64goeshere",
"ledger-hash": "someblake2orsha256hexencodedhash"
}
]
}}}
Proposed rule:
* Normal vendors will be allowed to only sign things in their namespace.
* If a developer owns multiple vendor namespaces, they will need
separate signing keys for each namespace.
* Transitive ownership across multiple vendor namespaces from a single
public key, or limited access to a single repository owned by another
vendor, should not be implemented at this level.
* At least one reserved vendor ID (e.g. `WordPress`) will be allowed to
issue core updates. It will function sort of like `root` on a UNIX-like
operating system. Access to this key should be scarce.
----
In addition to the technical details described above, we should have
notary services that either:
1. Rewinds the ledger to the genesis block and plays through each
subsequent update to ensure that the final state that WordPress sees is
deterministic.
2. Verifies that theme/plugin/core updates are reproducible from their
SVN/git commits, based on the metadata stored in the ledger.
3. Both 1 and 2.
=== What Guarantees Does Gossamer Offer?
First, it will provide absolute transparency into the public keys that are
trusted by the network as well as the updates that are delivered. This is
important for e.g. discouraging government backdoor requests. (You can't
silently backdoor WordPress if every update is unavoidably published on a
cryptographic ledger!)
For users with relaxed threat models, their trust can be delegated to
their hosting provider (or another appropriate third party) to
mirror/parse the ledger and inform them which keys to trust. This allows
them to offload a lot of complexity (which is great for low-powered or
low-storage devices e.g. on Raspberry Pi computers) to another third
party, which can also be kept honest through notaries.
Public key and update revocation is built-in.
Public key expiration isn't necessary to maintain security, but can be
baked in if so desired.
You don't need to deal with RSA signatures, basic constraints, or any of
the CA/B forum requirements for operating a Certificate Authority. (To
anyone curious, feel free to ask the ISRG, the operators of LetsEncrypt,
about how much work that is!)
== Great, So Where is Gossamer Today?
As I alluded to earlier, I'm writing a formal security proof for this
design. My intent is to submit it for peer review and inclusion in a
cryptology journal (and mirror it on IACR's ePrint archive, to ensure it's
available to the public).
If everyone involves is of the opinion that we shouldn't wait for all of
this to be complete, I can shift gears towards working on an
implementation sooner rather than later.
A lot of the designs in Gossamer (Chronicle, HERD, Quill, etc.) already
exist today, but aren't specifically designed for WordPress.
=== The Next Steps
Whether we move forward today or once academia has had adequate time to
review my designs, I'll spin up a separate Trac ticket for Gossamer. I'll
also set up a dedicated Github organization (or just reuse `bikeshedders`
from my IETF projects) for WP-Gossamer work.
When we've reached a point that everyone is confident in the designs, I'll
update the Trac ticket and issue patches or pull requests for all of the
relevant repositories. I would recommend merging it ''immediately after''
a major WordPress release to give everyone the maximum amount of time to
test it.
Because there's a lot of decisions left to make, I don't have an immediate
ETA on when Gossamer can be completed.
=== A Note on Resource Allocation
I understand that WordPress is a mostly volunteer-driven free software
project. If nobody in WordPress's core team has the spare cycles to
contribute to Project Gossamer, Paragon Initiative Enterprises intends to
carry it to the finish line by ourselves if need be. This work is too
important for the security of the Internet to neglect.
However, we will definitely need to know WordPress's preferences and
decisions throughout the process. If the participants in this thread can
commit to at least providing regular feedback (even as simple as "that
sounds good", "that sounds bad", or "I don't understand this") along the
way, that would be immensely helpful.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/39309#comment:91>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list