Description
Describe the bug
nix daemon
does not check signatures when registering realisations from untrusted sources.
Steps To Reproduce
On host A, build a non-deterministic CA derivation without signing it:
$ nix build --expr 'derivation { name = "test"; builder = "/bin/bash"; args = [ "-c" "echo $RANDOM > $out" ]; system = "x86_64-linux"; __contentAddressed = true; }' --no-sandbox --secret-key-files "" --no-link --print-out-paths
/nix/store/wdbn1y7mnkbzw2z1jjrfk42bc1yn1irv-test
$ nix realisation info --expr 'derivation { name = "test"; builder = "/bin/bash"; args = [ "-c" "echo $RANDOM > $out" ]; system = "x86_64-linux"; __contentAddressed = true; }' --no-sandbox --secret-key-files "" --json | jq
[
{
"dependentRealisations": {},
"id": "sha256:c31a4fe199a082f25be7d102076913c0ae0729624ffe1518151a567a2ffe66b4!out",
"outPath": "wdbn1y7mnkbzw2z1jjrfk42bc1yn1irv-test",
"signatures": []
}
]
Confirm that we are indeed untrusted by attempting to push an input-addressed derivation without a signing key:
$ nix copy --to ssh-ng://B --expr 'derivation { name = "test"; builder = "/bin/bash"; args = [ "-c" "echo $RANDOM > $out" ]; system = "x86_64-linux"; __contentAddressed = false; }'
error: cannot add path '/nix/store/ldhmb78xfnk1n2j38jxal8lj4vdihahs-test' because it lacks a signature by a trusted key
Copy the realisation from host A to host B as an untrusted user, which produces no error:
$ nix copy --to ssh-ng://B --expr 'derivation { name = "test"; builder = "/bin/bash"; args = [ "-c" "echo $RANDOM > $out" ]; system = "x86_64-linux"; __contentAddressed = true; }'
On host B, the realisation is indeed registered without a signature:
$ nix realisation info --expr 'derivation { name = "test"; builder = "/bin/bash"; args = [ "-c" "echo $RANDOM > $out" ]; system = "x86_64-linux"; __contentAddressed = true; }' --no-sandbox --secret-key-files "" --json | jq
[
{
"dependentRealisations": {},
"id": "sha256:c31a4fe199a082f25be7d102076913c0ae0729624ffe1518151a567a2ffe66b4!out",
"outPath": "wdbn1y7mnkbzw2z1jjrfk42bc1yn1irv-test",
"signatures": []
}
]
On another host C, it is also possible to substitute from B without a signature:
$ nix build --expr 'derivation { name = "test"; builder = "/bin/bash"; args = [ "-c" "echo $RANDOM > $out" ]; system = "x86_64-linux"; __contentAddressed = true; }' --no-link --print-out-paths --max-jobs 0 --substituters ssh-ng://B
/nix/store/wdbn1y7mnkbzw2z1jjrfk42bc1yn1irv-test
Interestingly, nix copy --from
does actually check for the signature:
$ nix copy --from ssh-ng://B --expr 'derivation { name = "test"; builder = "/bin/bash"; args = [ "-c" "echo $RANDOM > $out" ]; system = "x86_64-linux"; __contentAddressed = true; }'
error: cannot register realisation 'wdbn1y7mnkbzw2z1jjrfk42bc1yn1irv-test' because it lacks a signature by a trusted key
Expected behavior
- Nix daemon should not add realisations without a signature from untrusted sources.
- When querying a substituter, realisations without a signature should not be used to determine the output paths of a CA derivation.
nix-env --version
output
nix (Nix) 2.24.2
Additional context
According to RFC 0062, the signature of the realisation must be checked before being added to the local store.
Priorities
Add 👍 to issues you find important.
Activity