Any interest in checkings signatures while building packages?

I was just looking at the ethereum package and I typically try and validate the signature when I install it myself. It doesn’t seem like it’d be too hard to hard code the public key of creator of the software package and grab the signature & the download as part of the build process.

This could add just another step that an actor would need to modify to introduce a malicious package.

I saw that larger initatives for package signing have not made it through the early RFC/discussion stages (e.g. #613 and RFC0034) but this seems much more limited and could be introduced package by package.

What do y’all think? Worth the effort?

1 Like

In my naïve way of thinking, I don’t really understand why to check for signature, when most fetchers already require that you provide the hash of the fetched contents, so we already know that no one tempered with the contents.

if you’re downloading from a cache, the actual binary files are signed, if you would like to manually verify signatures, you could … but it would probably take forever.

Like @NobbZ said, all the sources require hashes, if you really wanted to, you could look at all the drv’s and inspect them for malicious intent, and then inspect the fixed derivation outputs as well.

Unless someone packages malicious software from an upstream source, it’s fairly difficult to introduce tampered outputs to nixpkgs.

Let’s be real here: We do not have the resources to check packages’ sources before updating them in nixpkgs and I would be willing to bet that it does not happen in practice.
I’m all for checking signatures - it would be a nice improvement over the protection against silent changes to the source we have right now with hashes.

The consequence would be that we’d only need nixpkgs committers to verify changes to the key, not check the signature on every update to get the security benefit of committer-checked signatures.

In theory it would be sufficient to check the signature only once in update scripts or something like that, but afaik those aren’t run on trusted infrastructure like builds are.

@hyperfekt exactly! It seems to me like it’d be a one off effort that yields a persistent security win.

To give a concrete example taken from https://github.com/NixOS/nixpkgs/blob/c623040a6280b9350c854a5c61495afca3326726/pkgs/applications/misc/electrum/default.nix

This package source is

  src = fetchurl {
    url = "https://download.electrum.org/${version}/Electrum-${version}.tar.gz";
    sha256 = "05ibrr6ysf6fncs1pimhxvyr7d659jwj2r2a9pdd3cmn1dxzy2w1";
  };

When it is updated the sha256 is updated. The sha256 ensures that whatever payload is downloaded at a later date is what was specified at the time that the package was updated.

The publisher of electrum, ThomasV, signs all downloads with the key found here. The corresponding signature for the latest download is found here.

It seems like it’d be pretty easy to bake in ThomasV’s public key into the build it’s self. This should keep the update burden the same and have no affect on the binary cache, but give an extra assurance that even under the situation where the download server or it’s SSL cert has been compromised the nixos package would fail to build, without any manual checking at PR review time.

Adding a public key per package sounds like another dimension of complexity that very few people want to put up with.

But sounds like a potential RFC topic.

1 Like

Right, so this protects against the attack vector where an upstream server, and consequently archive, is already compromised at the point when someone updates a derivation. As a result, they could accidentally submit the sha256 of the compromised archive.

I have also seen some PRs that just update the hash (no version bumps), because the upstream archive changed and as a consequence the hash is broken. Usually these are legitimate changes (some upstream developers just re-upload modified tarballs or change git tags), but the other possibility is that the archive is compromised. And its kinda hard to know with these PRs, unless the submitter contacts upstream, or there is some other strong evidence of what happened.

The last time GPG signatures came up in a PR, I also found this auto-closed PR that implements the suggested functionality:

Should in most cases be a one-time thing, right? Especially if the key was normalized by stripping signatures, etc. as suggested by @Ekleog suggested in the PR I linked above.

I agree. The cost of getting it wrong the first time may be big. Also, I guess it should be designed to be extensible since projects may use different tools for signing archives (e.g. signify). @Mic92 also raises a good question in that PR – whether it should be part of the build process or tooling, since it is something that only needs to be checked once for every version bump. When the archive is verified, the sha256 is enough.

Aside from the security added with pgp signed tarballs, me and fellow maintainers of sequoia, have encountered a situation where upstream provides a distribution tarball whose filename is sequoia-${version}.tar.pgp.gz and it turned out to be difficult to unpack it. It’d have been nice if stdenv was capable of doing so. However, practically, we concluded in that particular case that using these tarballs would have brought no benefit.