Why Package Signing is not the Holy Grail · caremad
donald stufft
Typically any time the topic of security and software packages, in my case<br>typically Python packages, comes up someone seems to come up with the “helpful”<br>suggestion of “Just Use X!”, where X is typically GPG but can be any of a wide<br>range of signing technologies. Quite often the people suggesting it have<br>latched onto signing packages as some sort of voodoo you can throw at the<br>problem and magically get “security”.
The Boring Easy Part
Generation of package signatures is actually a pretty simple thing to implement<br>assuming you’re using good libraries or tools to do it with. There is a number<br>of technologies from OpenPGP to NaCl to even commercially available<br>certificates from companies like Verisign. Most people look at the ease of<br>generating signatures, believe that’s all it takes, and declare it done.<br>You can see an example of this with PyPI/distutils. Here the GPG<br>signatures are able to be generated and even uploaded to PyPI and yet nothing<br>uses them, and even if they did they couldn’t be trusted.
The Hard Part that (Almost) No One Thinks About
When attempting to verify a signed file you check the signature against a<br>public key. If the signature matches that public key then everything is kosher.<br>The question then becomes which public key, and therein lies the rub. If<br>you do not have a well defined model of trust then all you’ve done is thrown<br>cryptography at a problem in order to give the people involved the ability to<br>say that their system has signature verification.
Let’s Just Ask The Delivery Guy
One naive solution would be to simply upload the public key to the repository<br>as is done with PyPI. Then clients can simply download the public key and<br>verify it against the signature! However in this model if someone is able to<br>send you a malicious package they are also likely able to send you a malicious<br>key. Once they’ve sent you the malicious package and the malicious key your<br>client will happily verify it, claim all is well, and install it. If you trust<br>the repository to deliver to you the expected signing key and the package to be<br>verified you’ve gained nothing and introduced complexity.
Linux Has Packaging Signing, Let’s Steal Theirs
Another solution to solving this is to look at prior art and steal what they’ve<br>done. The most oft pointed to example is various flavors of Linux. On the<br>surface it looks like exactly what people want. When you install your Linux it<br>comes with a public key baked into the image and anytime you install packages<br>it verifies against that public key. You’re no longer implicitly trusting the<br>repository to tell you what key you should trust because you already know<br>what key.
However, this has a number of issues too. The first issue that a repository<br>like PyPI would have with this system is simply one of scale. Debian or<br>Red Hat have a small pool of developers who are able to make new packages,<br>making it easy to properly verify each person and sign their keys or otherwise<br>give them access. PyPI allows anyone to sign up and make a release which<br>makes verifying authors an unmanageable problem.
The second issue is that in addition to trusting the package authors, you are<br>trusting the entire build chain involved in producing the package. You don’t<br>have to trust the repository which hands you the package, but trusting one<br>machine up the chain isn’t all that different. If that machine got compromised<br>you could generate malicious packages that tools would blindly install. This<br>system does have one major advantage in that you have mirror validation built<br>in. Since the validation is based on the package, not on the mirror you<br>downloaded from, as long as the signature is valid you know it came from the<br>trusted build machine.
Everyone is Connected, The Web of Trust
At this point in the argument, someone will typically bring up the web of trust<br>available in OpenPGP and say that it doesn’t require trusting a single machine<br>nor does it require a small team to verify each author. This is getting much<br>closer to a solution that technically is almost a solution but it’s lacking<br>a very critical piece.
With the OpenPGP Web of Trust you’re signing the identity of the author. What<br>you’re not doing, and what there is no method of doing to my knowledge, is<br>gaining any assurance that the person whose identity you’ve verified has any<br>right to sign the package you’re verifying. This means that if you trust Bob<br>because you want to use his “foo” package, you also trust him to sign for the<br>“bar” package, even though that belongs to Alice. This brings us back to the<br>original problem of trying to determine if the key we have is trusted for this<br>package.
The other major problem with the Web of Trust is its user experience. If<br>you start requiring every person...