-
-
Notifications
You must be signed in to change notification settings - Fork 162
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
[RFC 0034] Expression Integrity #34
Closed
Closed
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
--- | ||
feature: expression-integrity | ||
start-date: 2018-09-28 | ||
author: lrvick | ||
co-authors: | ||
related-issues: | ||
- https://github.com/NixOS/nix/issues/404 | ||
- https://github.com/NixOS/nix/issues/613 | ||
- https://github.com/NixOS/nix/issues/748 | ||
--- | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
This RFC seeks to provide a strategy to allow NixOs to strongly attest who | ||
authored a nix expression, who reviewed it, and that it has not been tampered | ||
with outside the review flow. | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
Due to the lack of VCS integrety on NixOS today a bad actor can gain remote | ||
code execution on NixOS systems if any of the following are true: | ||
|
||
* A Github employee is coerced or malicious | ||
* The Github account credentials of any maintainer are compromised | ||
* A successful (even limited) MITM attack on github.com | ||
|
||
Essentially NixOS has many single points of trust, and thus single points of | ||
failure. | ||
|
||
This is a serious design flaw and we can learn lessons from other package | ||
management systems that have been burned by similarly poor package management | ||
designs. | ||
|
||
See examples of major security incidents in other package managers: | ||
|
||
* Gentoo: https://archives.gentoo.org/gentoo-announce/message/dc23d48d2258e1ed91599a8091167002 | ||
* Debian: https://lists.debian.org/debian-devel-announce/2006/07/msg00003.html | ||
* NPM: https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes | ||
* PyPi: https://www.reddit.com/r/Python/comments/8hvzja/backdoor_in_sshdecorator_package/ | ||
* Ubuntu Snap: https://github.com/canonical-websites/snapcraft.io/issues/651 | ||
* Arch Linux AUR: https://lists.archlinux.org/pipermail/aur-general/2018-July/034153.html | ||
|
||
# Detailed design | ||
[design]: #detailed-design | ||
|
||
## Package Contributor | ||
|
||
### Workflow | ||
|
||
1. Author and test a nix expression | ||
2. PR a signed commit adding nix expression to NixOS/nixpkgs repo | ||
|
||
### Notes | ||
|
||
* Can be enforced by mandating all commits be signed in VCS settings | ||
* Contributors who choose not to sign will need someone else to PR for them | ||
|
||
## Package Maintainer | ||
|
||
### Workflow | ||
|
||
1. Verify signing key ID is listed in maintainers list | ||
* Add key ID to maintainers list if not already present | ||
2. Verify signature on PR matches public key id in contributors list | ||
* Add key ID to contributors list if not already present | ||
3. Review content of new PR for general best practices | ||
4. Ensure signatures/hashes verified for third party code referenced | ||
5. Make signed merge commit to master of NixOS/nixpkgs | ||
|
||
### Notes | ||
|
||
* Maintainer signatures should be a hard requirement | ||
* Maintainer and Contributor should never be the same person. | ||
|
||
## Nix Clients | ||
|
||
### Workflow | ||
|
||
1. Pull latest nix expressions from VCS repo | ||
2. Verify author/reviewer commit signatures for all nix expressions | ||
3. Build/Install nix expression | ||
|
||
### Notes | ||
|
||
* Local building is required for integrity as no trusted cache system exists | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
Some contributors to NixOS may no longer contribute if doing so requires some | ||
additional security work. | ||
|
||
# Alternatives | ||
[alternatives]: #alternatives | ||
|
||
## Git Notes signing | ||
|
||
Reviewer/maintainer signatures could be added to the Git Notes interface on | ||
a given ref allowing m-of-n signing for security critical expressions. | ||
|
||
This would additionally negate the need for merge commits and would allow | ||
VCS automatic merging to be used if desired. | ||
|
||
## Patch ID | ||
|
||
One could chose to sign a Git "patch-id" instead of a given ref hash. This | ||
would allow signatures to still be valid even if a git rebase was done that | ||
didn't add any LOC changes to a given changeset. This could add flexibility | ||
but will need more testing. | ||
|
||
Example: | ||
|
||
``` | ||
git diff-tree -p "someref"..HEAD | git patch-id --stable | gpg -as | ||
``` | ||
|
||
## Detached signatures | ||
|
||
We could avoid using VCS level signing at all and simply mandate maintainers | ||
add their detached .nix.sig files to a PR before it merges. | ||
|
||
# Unresolved questions | ||
[unresolved]: #unresolved-questions | ||
|
||
Currently this scheme does not attempt to solve how to tie trusted cached | ||
binaries to their signed VCS commits. Until a solution for this is reached | ||
users will have to build every expression locally which makes securely using | ||
NixOS impractical on low-spec systems or users with limited time to wait on | ||
compiles. | ||
|
||
There are other proposals in progress to address this. | ||
|
||
# Future work | ||
[future]: #future-work | ||
|
||
It may be desireable to continue to have an untrusted expression repo like the | ||
one used today that users can install from by hand as they please. | ||
|
||
This could be an analogue of the Arch Linux User Repository (AUR) vs the | ||
trusted/signed official repos. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We actually have something similar already at https://github.com/nix-community/nur |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eh?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the misunderstanding lies in "cache system I can trust"/"trust-less cache system" vs "cache system that requires trust"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the current artifact hosting system is compromised, it is game over and clients will blindly trust malicious builds.
It is only when you have signing by each maintainer -or- a highly transparent reproducible build system that clients will have a way to notice if an artifact server is compromised. Much the same way debian users can trust any random http/ftp mirror today, because the client will verify the hash and the maintainer signature on that package. Any system that trusts a single individual or computer is not compromised, is bound to be abused.
This RFC if implemented would only protect users building from source as only the nix expressions themselves would have signatures by both the creator and reviewer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think maybe you misunderstand what our Hydra is? It doesn't host artifacts, it is a build server. Its results are uploaded to our binary cache. Nothing a maintainer builds goes to the binary cache. Maintainers cannot upload to the binary cache. There is no way for a maintainer to sign the NAR in the end, because the maintainer has no part in its creation. Other distributions do this because they put a great deal of trust in the maintainer to not backdoor the artifacts. We don't, because, well, we don't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that it blindly pulls code from github without verifying it, then blindly builds/signs artifacts. This is honestly awful security. Instead of an individual maintainer/reviewer pairs that can at worst only backdoor their own package, you have a central system that can backdoor any package at any time, and so can those with remote access to that build system.
Because hydra signs anything without code review or verification of signatures from code reviewers it means you need absolute trust in Github, in Hydra, the network that connects them, every person with shell access on the Hydra machines, and every one with push access. This is imo highly irresponsible and honestly puts every individual with that much solitary power in a non obvious position of personal risk.
As one practical example: If I had a remote shell exec 0-day I would use it gain remote access to hydra to inject a small hard to detect change just before compilation in major bitcoin wallet packages that compromises the random number generator allowing me to factor keys. I would then wait for a big enough wallet balance years later and take it all. I could also blackmail a hydra maintainer to do it for me as the potential payout is worth it. I could also phish the github credentials of one person with commit access, turn off notifications, and rewrite history quickly just after the next change to that package. Hydra can't hope to deliver trusted outputs until it can verify its inputs and independant copies of it can be run with different maintainers that all get the same results (reproducible builds). We can't even begin to solve that problem until we have a trusted signed tree of package definitions without a SPOF.