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

stream metadata GPG validation #774

Open
cgwalters opened this issue Mar 24, 2021 · 6 comments
Open

stream metadata GPG validation #774

cgwalters opened this issue Mar 24, 2021 · 6 comments

Comments

@cgwalters
Copy link
Member

cgwalters commented Mar 24, 2021

In stream metadata today we have signatures on the individual artifacts. I'd like to have a model where the whole stream metadata is signed too - this greatly mitigates things like MITM downgrade attacks, etc. It would also cover e.g. the AMIs, which are not signed today.

For signing the JSON...having a detached stable.json.asc is an obvious approach but external signatures on unversioned URLs lead to race conditions around fetches: http://www.chiark.greenend.org.uk/~cjwatson/blog/no-more-hash-sum-mismatch-errors.html
(Fun side fact: Colin Watson and I worked together sometimes in Debian, and people got us confused quite frequently)

For inline signatures I found https://jwt.io/introduction - not sure if there's a better standard, and probably that one's a nonstarter because it breaks the format.

If we go with the detached model, one thing that would help is if e.g. the stable URL was actually a HTTP redirect to something like https://builds.coreos.fedoraproject.org/streams/stable-${sha256}.json - then a client could detect the redirect and then reliably fetch the detached signature from https://builds.coreos.fedoraproject.org/streams/stable-${sha256}.json.asc for example.

@bgilbert
Copy link
Contributor

It wouldn't prevent downgrade attacks by itself, since the entire stream metadata could be downgraded. But the client could check that the last-modified date doesn't go backwards.

Intercepting redirects feels like it would require the client to have too much knowledge of the network protocol. Maybe we could have a new stable-signed.json which just contains URLs for the current stable-${sha256}.json and stable-${sha256}.json.asc.

cgwalters added a commit to cgwalters/stream-metadata-go that referenced this issue Mar 26, 2021
Most callers will want this.  Additionally, if we ever add
more integrity for the stream such as GPG signing, this will
be the place to do it.

xref coreos/fedora-coreos-tracker#774
@cgwalters
Copy link
Member Author

It wouldn't prevent downgrade attacks by itself, since the entire stream metadata could be downgraded. But the client could check that the last-modified date doesn't go backwards.

Right.

Maybe we could have a new stable-signed.json which just contains URLs for the current stable-${sha256}.json and stable-${sha256}.json.asc.

Yeah. I found various bits on this:

And the JWT is also an approach.

I think what you're suggesting is quite simple and straightforward - easy to implement, but would be custom to us and also require 3 distinct HTTP round trips.

We also have the broader problem that validating GPG signatures in general sucks, but it's particularly painful with Go projects that want to statically link everything. It's may be worth opening up the conversation around moving away from GPG for this.

I dunno.

cgwalters added a commit to cgwalters/stream-metadata-go that referenced this issue Mar 26, 2021
Most callers will want this.  Additionally, if we ever add
more integrity for the stream such as GPG signing, this will
be the place to do it.

xref coreos/fedora-coreos-tracker#774
@bgilbert
Copy link
Contributor

See also #826, which is the same issue for a different set of metadata.

@rugk
Copy link
Contributor

rugk commented May 11, 2021

It wouldn't prevent downgrade attacks by itself, since the entire stream metadata could be downgraded. But the client could check that the last-modified date doesn't go backwards.

I guess you know https://theupdateframework.io/ for a way how to prevent downgrade attacks. It also describes all the problems and other attacks (threat models) associated to the whole thing of “updating” software. 😉

@lucab
Copy link
Contributor

lucab commented May 12, 2021

A bunch of assorted self-notes that we may or may not want to dig deeper:

  1. to avoid both "inline signatures embedded in JSON" and "racing on detached signature files", we may look into generating a detached signature and sending it to the clients as a custom HTTP response header.
  2. minisign sports small keys and signatures, and it has native libraries for verification for all the languages we use (Rust, Go, Python).

@jlebon
Copy link
Member

jlebon commented May 12, 2021

The signature-in-header approach sounds interesting.

Another more low-tech approach is to have the detached signature not have a stable name and point to it from the metadata itself in e.g. metadata.signature_path. On the signing side, we would: choose a name, add it to the metadata, sign the metadata, upload the signature, and then upload the new metadata, and finally GC old signatures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants