Homebrew / brew

🍺 The missing package manager for macOS (or Linux)
https://brew.sh
BSD 2-Clause "Simplified" License
41.21k stars 9.69k forks source link

Support GPG Signature Verification for Formulas #5852

Closed elaine-jackson closed 5 years ago

elaine-jackson commented 5 years ago

A detailed description of the proposed feature

Homebrew formulas will have an optional ability to enforce GPG Verification by a specific key or set of GPG keys. Software projects such as Tor, Tor Browser, and GPG itself are high risk packages and extra sets of verification against sophisticated adversaries are necessary. When installing as well as displaying the SHA256 is valid, it would say the binary / source code package was signed off by each Name <email> <key id>.

The motivation for the feature

The feature will provide a secondary measure to ensure a package hasn't been tampered with. Additionally it will provide proof the author has signed off on the build.

How the feature would be relevant to at least 90% of Homebrew users

GPG Verification ensures that the author who created the software package has personally signed off on the source code or binary as being legitimate.

What alternatives to the feature have been considered

Currently Homebrew just checks the SHA256 hash. This means whoever is maintaining a specific formula has briefly checked that the source is legitimate. In practice though, if a website was compromised a maintainacer might not notice. Which maintainers here is checking that packages are GPG signed before calculating the SHA256 sum for a new / update to, a (high risk / all) formulas? How do we ensure contributors do the same? The short answer is we can't, but checking the GPG Signature provides an extra form of verification for high risk packages.

colindean commented 5 years ago

I think this is a good candidate for an external command that could be upstreamed if it gains usage.

elaine-jackson commented 5 years ago

I think this is a good candidate for an external command that could be upstreamed if it gains usage.

Is there a guide on creating external commands? I'd be interested in implementing this. Just one minor note, the idea does involve adding data to formulas so Homebrew knows which signatures to expect and trust.

scpeters commented 5 years ago

I don't know of a guide, but one example is livecheck:

I believe the pattern is to host data for each formula in the separate repo until perhaps one day it could be merged into the formulae in homebrew-core

MikeMcQuaid commented 5 years ago

I don't understand the attack that is prevented by GPG signing but not SHA256 here.

In practice though, if a website was compromised a maintainer might not notice.

This has happened before and we notice because the SHA256 has changed. We never update these blindly without investigation.

The short answer is we can't, but checking the GPG Signature provides an extra form of verification for high risk packages.

If we can't then I'm not sure I understand how this adds any security without asking users to specifically accept specific GPG keys for packages. On top of that: how do we ensure they don't blindly accept any key?


In short: I'm not currently sure this improves security in any meaningful way but it will definitely increase the overhead for maintainers.

chdiza commented 5 years ago

Is there a guide on creating external commands?

Yes, right on the front page of docs.brew.sh: https://docs.brew.sh/External-Commands

elaine-jackson commented 5 years ago

I don't understand the attack that is prevented by GPG signing but not SHA256 here.

In practice though, if a website was compromised a maintainer might not notice.

This has happened before and we notice because the SHA256 has changed. We never update these blindly without investigation.

The short answer is we can't, but checking the GPG Signature provides an extra form of verification for high risk packages.

If we can't then I'm not sure I understand how this adds any security without asking users to specifically accept specific GPG keys for packages. On top of that: how do we ensure they don't blindly accept any key?

In short: I'm not currently sure this improves security in any meaningful way but it will definitely increase the overhead for maintainers.

SHA256 hash verification says a Homebrew Maintainer checked the hash and says its safe, its not proof that the author signed off on it. It's security in-depth, I'm not saying that checking the SHA256 hash is bad just that an extra fofrm of verification would come in handy.

MikeMcQuaid commented 5 years ago

SHA256 hash verification says a Homebrew Maintainer checked the hash and says its safe, its not proof that the author signed off on it. It's security in-depth, I'm not saying that checking the SHA256 hash is bad just that an extra fofrm of verification would come in handy.

Not quite, in some cases the authors publish the hashes so they do provide additional verification.

Can you please elaborate on the actual attack this would stop? For "proof the author signed off on it" we would need a way to programmatically know (at a minimum) who are all the possible authors for a package so they can be automatically verified. How do we decide who to trust and who to not? Printing out that information for users to verify themselves just encourages people to ignore that text which will 99.9% of the time be exactly the same.


Another thing worth noting is that most packages to most users are delivered as binaries so they would never touch this workflow at all in that case.

elaine-jackson commented 5 years ago

SHA256 hash verification says a Homebrew Maintainer checked the hash and says its safe, its not proof that the author signed off on it. It's security in-depth, I'm not saying that checking the SHA256 hash is bad just that an extra fofrm of verification would come in handy.

Not quite, in some cases the authors publish the hashes so they do provide additional verification.

Can you please elaborate on the actual attack this would stop? For "proof the author signed off on it" we would need a way to programmatically know (at a minimum) who are all the possible authors for a package so they can be automatically verified. How do we decide who to trust and who to not? Printing out that information for users to verify themselves just encourages people to ignore that text which will 99.9% of the time be exactly the same.

Another thing worth noting is that most packages to most users are delivered as binaries so they would never touch this workflow at all in that case.

The formula would have two properties added to it. A boolean set to true declaring to check GPG Signatures, and a string array of key ids. The package would only be trusted with valid signatures from all key ids. Of course Homebrew Maintainers, as with any other package system, would be responsible for verifying the key ids are legitimate.

MikeMcQuaid commented 5 years ago

Of course Homebrew Maintainers, as with any other package system, would be responsible for verifying the key ids are legitimate.

It's unclear how they would do that if we assume that the upstream website cannot be trusted (and if it can: SHA256 is sufficient).


Closing this as despite multiple requests no detail has been provided on what attack this would stop.

lunarthegrey commented 5 years ago

I think this should be reopened and considered further. It shouldn't require any devs to sign their packages with GPG keys, but encouraged. It could also be done automatically (but with more complexity) via homebrew where the casks would have a link to the GPG signature that periodically gets updated when hashes change (like apt/yum repositories do). I'm unsure what checks you do when a SHA hash changes (virus scanning is not enough), but the hash alone is not a great way of verifying if it's legitimate.

The attack scenario would be as follows..

An attacker gets hold of a website that homebrew pulls a binary from. They secretly replace the binary with a malicious one (thus the hash changes). They also change the hash listed on the website (this is a bad thing that most devs do, listing the hash on the same website a binary is downloaded from without further verification). During this event the website maintainers are completely unaware of this. The attacker or someone else could then submit a pull request for the new hash and it would be blindly accepted.

With the devs signing the hashes with their GPG keys it would provide one more step the attacker would have to take. They'd have to compromise their GPG key in order to sign the new hashes.

MikeMcQuaid commented 5 years ago

It could also be done automatically (but with more complexity) via homebrew where the casks would have a link to the GPG signature that periodically gets updated when hashes change (like apt/yum repositories do).

If this was done automatically it would mean if I compromise the web server I can sign with my own, newly generated key and it would be automatically accepted.

I'm unsure what checks you do when a SHA hash changes (virus scanning is not enough), but the hash alone is not a great way of verifying if it's legitimate.

A hash doesn't verify it's legitimate but it verifies it is unchanged. To echo your words back at you: verifying that something has been signed with a GPG key is not enough; you have to verify the author is valid and expected.

An attacker gets hold of a website that homebrew pulls a binary from.

Homebrew does not deliver binaries to end users. It uses binaries in exception circumstances when bootstrapping is impossible without them.

The attacker or someone else could then submit a pull request for the new hash and it would be blindly accepted.

No, it would not. We don't blindly accept hash changes.

With the devs signing the hashes with their GPG keys it would provide one more step the attacker would have to take. They'd have to compromise their GPG key in order to sign the new hashes.

Not if it was done automatically with a link to the GPG signature. If you instead embed the valid authors in the formula: how does a Homebrew maintainer verify those are legitimate? How does an upstream project add new authors/keys? How does it revoke keys?


Can anyone commenting in here please take the time to read ALL of the above comments in full before commenting, please. This thread will be locked if I have to keep restating the same things again and again.

lunarthegrey commented 5 years ago

I think I'll just leave this discussion as is as you seem aggressive with your ideas and not willing to take in other opinions, thus closing the issue and threatening to lock it. I'm unsure how you verify that the new package (generally referring to casks) is legitimate unless you speak with the developer personally. This is why common Linux package managers such as apt or yum verify GPG signatures.

MikeMcQuaid commented 5 years ago

@lunarthegrey I am very open to other opinions. I am not open to incorrect statements going unchallenged or having to restate things multiple times. Bear in mind if you are asking the Homebrew maintainers to implement and/or run a system involving GPG signatures: you have to convince us and not the other way around.

vitorgalvao commented 5 years ago

I'm unsure how you verify that the new package (generally referring to casks) is legitimate

From your earlier comment, I was under the impression you were confusing the two. To clarify, this issue is about formulae, not casks. Since they are built differently, they require separate discussions, and we already had this discussion regarding casks.

We had a GPG stanza in casks for years, from before the projects merged. It was just a stub because there was never enough interest from anyone in making it a reality. We eventually decided to not have it.

As to your question, the way we ensure the package is legitimate (casks) is by quarantining downloads. In other words, we realise there’s only so much a small team of volunteers can do, so we shifted the burden to Apple’s own system (Gatekeeper).

iMichka commented 5 years ago

An attacker gets hold of a website that homebrew pulls a binary from. They secretly replace the binary with a malicious one (thus the hash changes). They also change the hash listed on the website (this is a bad thing that most devs do, listing the hash on the same website a binary is downloaded from without further verification).

pulls a binary from: for formulae we do not pull binaries (or we try to avoid this, I think we may have some precompiled stuff somewhere to bootstrap more complex formulae though).

I guess you are talking about source code that can be downloaded from upstream websites. From a Linux perspective, I am not aware that debian or fedora require this kind of security level from the initial source code. So I don't understand why we should implement that kind of thing.

By the way: if upstream is compromised, you should complain to upstream. We are just a package manager. We do our best to double-check nothing fishy is ongoing, but the source code that is delivered by upstream is under their responsibility, not ours.