Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Case: Least Authority CDN Serving #425

Closed
wants to merge 1 commit into from

Conversation

davidstrauss
Copy link

@davidstrauss davidstrauss commented Apr 25, 2019

While working on the security architecture for Drupal's planned auto-update features, I realized that many of our use cases could be solvable using SXG rather than rolling our own signing mechanism (as APT and Yum have) to support offline signatures for metadata from update servers. We already intend to distribute the metadata via a CDN that has appropriate certificates for drupal.org, but we also don't want the attack surface introduced by every POP being a potential point of compromise. Given that we control the client side in these scenarios, SXG represents one brightly lit path to trusting the metadata without relying solely on TLS or using baroque integrations with GnuPG.

@davidstrauss davidstrauss force-pushed the patch-1 branch 4 times, most recently from e912f38 to b2e8937 Compare April 25, 2019 23:04
Copy link
Collaborator

@twifkak twifkak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fly-by comment; not a full review, which I'll leave to @jyasskin.

applications, and server applications.

SXG would also offer a foundation for dynamically imposing such client
behavior using a mechanism similar to HSTS. This would allow supporting clients
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if Must-Staple is a closer analogy to what is required. An origin could not enforce that their CDN includes a certain HTTP header on all responses, but they could enforce that the only certificate they bestow upon the CDN has a given extension. (As to whether that extension could or should be marked critical, I'm not sure.) Supporting clients would, when confronted with a TLS connection backed by such a cert, only honor responses that are signed with an SXG cert.

Copy link
Author

@davidstrauss davidstrauss Apr 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if Must-Staple is a closer analogy to what is required.

Perhaps I should rephrase the text, as the forward-looking idea is less about the mechanism (HSTS-style, Must-Staple, or otherwise) and more about allowing a site to inform clients to expect SXG responses. That expectation should be sticky or, at least, resistant to downgrade attacks.

I agree that an extension applied to the TLS certificate would be a technologically elegant way to solve the issue. I'd argue that such an extension should be non-critical, as that would allow existing clients to interact as before, while clients aware of the extension could enforce SXG on responses. SXG enforcement is a defense-in-depth against POP/proxy compromise, which I think is another argument for a non-critical designation.

I try to push back against new certificate extensions for practical reasons, though. They create a barrier to entry for people who implement or deploy the design. That raises some reasons I looked first to HSTS: it's broadly used, doesn't require external facilitation (e.g. by a CA), and has no up-front or ongoing costs to web site administrators.

An origin could not enforce that their CDN includes a certain HTTP header on all responses, but they could enforce that the only certificate they bestow upon the CDN has a given extension.

This is true, but what I had in mind was the broader world of HSTS rather than just the header. In practice, qualifying HSTS headers get cached in browsers and bundled into the HSTS Preload List, both of which continue enforcement even if the header goes missing. (So, while a compromised POP could stop sending an SXG enforcement header, clients would still expect SXG.) I'm unsure whether this is the most desirable approach to SXG enforcement, but it's one established pattern that's possible to apply here.

Copy link
Member

@jyasskin jyasskin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, sorry for leaving this review for so long.

I believe I convinced @davidstrauss a couple months ago that his underlying use case was better served by signify or minisign. (I found those via https://latacora.micro.blog/2019/07/16/the-pgp-problem.html.)

However, I believe there are two interesting use cases here:

  1. The one in the title, letting CDNs serve a site without letting them change the content. This one is difficult and requires at least two exciting components beyond signed exchanges:

    1. The CDN, by definition, gets the traffic that looked your origin up in DNS. That means it also gets the traffic from a CA trying to verify who owns the domain using method 3.2.2.4.6 Agreed-Upon Change to Website, so it can just get a new certificate as your origin. This might be solvable using CAA and some "I got here first" account restriction with the allowed CAs, but that seems fragile, so it might be worth designing something else.
    2. As @mnot pointed out, when the browser tries to create a connection to your origin, it checks that the target (the CDN) has the private key for a trusted certificate for that origin, which the CDN of course can't have if we don't want them forging content. As Mark said, we'd need to invent a way for the server to tell your browser to create the "TLS" connection but only accept content within valid SXGs. And to preserve confidentiality against network attackers other than the CDN, we'd need to actually authenticate the CDN itself in some other way. And I don't see a way for a server to migrate to this scheme while still supporting old clients. Mark suggests LURK, which I don't understand well enough to endorse.
  2. Ensuring users get correct content even if your frontend is compromised. (And it might be reasonable to think of an evil CDN like a compromised frontend.) I think the HSTS-like mechanism proposed here actually accomplishes this, and we don't need the complexity of origin-trusted certificates to get here. Instead, you'd serve a TBD-Content-Public-Key-Pins: ed25519=(*base64-public-key* ...), max-age=seconds header which the client would trust on first use, and subsequent responses would only be trusted if they were signed by that public key. You'd store the private key in your build system but keep it away from frontends. This is similar to Signature-based SRI but works on top-level resources. Note that this has footguns very similar to Public Key Pinning. Apps like end-to-end encrypted messaging systems and password managers would probably be interested in using this.

I propose to add both use cases to this document with descriptions like above, with a note that I don't expect the CDN use case to happen any time soon. I'll send 2 PRs.

@davidstrauss
Copy link
Author

davidstrauss commented Oct 17, 2019

I believe I convinced @davidstrauss a couple months ago that his underlying use case was better served by signify or minisign.

We were convinced! We have a working implementation in testing now:

However, we extended the Signify design to support expiring intermediate keypairs. We did this for two reasons, which I'll mention here because SXG does support this use case (via X.509) better than Signify's design:

First, Drupal needs to sign artifacts produced in its online build infrastructure. These artifacts include builds of community-provided code that may be malicious. Signing these builds requires the key -- or the ability to sign -- to be available to this high-risk system. However, most cloud HSMs don't support ed25519. We don't have a natural place to deploy custom hardware for the Drupal Association, so we opted for using a VM as a signing oracle (to still create some isolation in case of build server compromise). Still, we wanted to anchor trust in something other than a key deployed to a VM in the cloud.

Second, Drupal lacks a natural key rotation interval akin to OpenBSD's six-month-ish release cycle. Drupal's major releases get support for years, and users expect to be able to upgrade across fairly arbitrary point releases. This creates tension between (a) rotating across point releases (perhaps not every one) and potentially breaking the ability of older point releases to validate current builds versus (b) rotating across major releases and having keys live for 5+ years. It would also be possible to have (c) older point releases "walk" their way to trusting the current build key, but that seemed fragile. An intermediate keypair makes rotation a question of operations effort versus security -- with no end-user impacts.

So, an intermediate keypair seemed like an elegant way to keep the root offline and support arbitrary rotations of the secrets in the deployed build infrastructure. (We currently hope to rotate intermediate keys quarterly.) Otherwise, we were quite happy with what Signify provided as a design.

We plan to secure the offline root by using YubiHSM hardware.

Base automatically changed from master to main February 17, 2021 00:19
@hayatoito
Copy link
Collaborator

[PR Triage]
I'm marking a label of "consider closing" for a PR which has not been active recently.
If there is no activity in a month, we will close PRs tentatively. Thanks!

@hayatoito
Copy link
Collaborator

Closing.

@hayatoito hayatoito closed this Dec 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants