Why Package Signing is not the Holy Grail (2013)
caremad.io
caremad.io
It seems to me that there are two main vectors to approach this problem:
First, massive simplification of all of our systems. (I call this "The Complexity is Too Damn High!" problem.) Other than certain niche applications we have enough processing power to run civilization. Rather than rushing the Singularity, let's take a breather and consider?
Second, trustworthiness and integrity have to become foremost values, and an international ad hoc web-of-trust has to be established. I know it sounds crazy, and maybe it is, but the alternatives seem even crazier, no?
We really need a global ad hoc web of trust. But the problem is that the web links can't be like anything we have ever tried on a large scale. They need to be distributed, personalized and contextual, and all the trend on the software market nowadays is towards centralized, one size fits all and no-choices needed.
I'm more optimistic about the simplification.
> But the problem is that the web links can't be like anything we have ever tried on a large scale. They need to be distributed, personalized and contextual
What do you mean?
This is wrong. What we are trusting is the package author. In Node.js land, I trust the author of Express, because they have provided an awesome library that I and many others have gotten years of use out of. I used to trust Marak, but after his recent injection of malicious code into two of his popular libraries, I don’t anymore, and I won’t use code from his projects. When I want to install an npm module in a project from an author I’ve never used before, I go read the source of their package so I don’t have to trust them (in many cases this has led me to find a number of bugs, and end up switching to another project).
Knowing that the same person who released the previous version of this package also released the next version definitely has value to me. A pinned key, like ssh uses, would have value. Is it perfect? Far from it. Is it better than nothing? For me, absolutely.
The linked article and the resulting discussion will have almost no value. The post is old, and doesn't make a coherent argument other than one of inaction. It would be best to leave it alone and let it drop off the main page.
----
Do nothing, because it won't cover all the corner cases.
No one said it was the Holy Grail (or the Holy Hand Grenade). You want UNSIGNED packages? This post is a distraction.
> This system does have one major advantage in that you have mirror validation built in. Since the validation is based on the package, not on the mirror you downloaded from, as long as the signature is valid you know it came from the trusted build machine.
PyPI should have already worked this way when the post was made. The mess that is PyPI shouldn't be used as evidence for anything other than PyPI is a mess.
I don't belive you can upload public keys to PyPI.
(In the deep past you could put 32-bit(!) OpenPGP key ID in your PyPI profile, but that's it.)
If you've been using a package for some time and suddenly the key changes, that's auditable. It won't impact anyone whose first use is after that point, and it's unlikely that end users will care, but for an organization, sure, that's meaningful. I'd go open an issue and ask why that happened, and pay attention to that commit.
> What you’re not doing, and what there is no method of doing to my knowledge, is gaining any assurance that the person whose identity you’ve verified has any right to sign the package you’re verifying.
Presumably we can just do what the web does with certificates tied to domains.
> Another suggestion I’ve seen is adopting a model similar to that of SSH, that is the first time you install a package you’re prompted to accept the key and from then on out it will remember that and use that as the trusted key.
Ah nice, this addresses my first point.
> Packages on PyPI change hands, get deleted, or even have multiple authorized releasers.
This is a feature :P
I definitely want to know if a package changes hands!
As for having multiple keys valid for a single package, I feel like that isn't much of an issue? I think we can look at certificates again for how this would work.
> If they go to PyPI to find out then we are back again at trusting the repository implicitly. If they don’t go to PyPI they are most likely to just hit whatever lets them install, training them to just do what it takes to install and ignore the warnings and prompts
For users, yes. For organizations, no. I'll absolutely investigate why a key changed. And when I see that it's malicious I'll let users know, just cause I'm so nice.
> Even if we wave our hands and give ourselves the perfect way to transmit trust, as long as PyPI is the authority over who owns a particular name then we must implicitly trust PyPI to tell us who is allowed to release which packages.
I'm confused by this part. Why is that the case? If I sign on my machine before I push to PyPI, how would PyPI be the authority? Unless this is referring to "PyPI can change the public key", which is true, but as I mentioned that's auditable and will raise lots of flags.
> It’s important to remember that the only thing any of these systems are able to verify is that the package you’ve fetched is the package you wanted, nothing more.
For sure.
> This isn’t an already solved problem nor is it an easy to solve one.
Yeah, unfortunately the tooling just isn't really there, so the UX is weak, so no one does it... and it's hard to go back and retroactively do so. In an ideal world this would all sort of Just Work, and it would be universal, so you could cryptographically verify your packages, your commits, your builds, your binaries, your containers, etc.
I wouldn't blame anyone for not doing these things today. There's no support for it. But if we got support, it would be a win.
Just what we need. Lets turn the concept of DNS into even more of an SPOF.
It is a solved problem, the solution is just politically inconvenient for us: only trust the OS vendor’s signing keys, treat them as benevolent dictator of our computing, and have them censor[0] those who we hope are malware authors, on our behalf.
Of course, there are all sorts of other problems unrelated to the provenance of the signers; npm is notorious for making basically all of those mistakes. But there absolutely is no good antimalware solution that does not require human review. There has to be someone in the mix to actually look at the code and make sure it’s nonmalicious.
Unfortunately, this also grants the person doing the reviewing power over your computing habits, in two ways:
1. They can refuse to sign a benign package on non-security grounds, such as a political disagreement with the package owners, taking offense to what the application does, or not wanting to sign a package that violates copyright in some way[1].
2. They can agree to sign a malicious package, either because they make more money doing so, because they want to compromise or extort their users, or because someone else compromised and extorted them into shipping malware.
#1 is why the App Store sucks and #2 is why alternative stores suck more. This is not a technical problem; this is a governance and alignment problem. Linux distros sidestepped this problem mainly by being non-profits with a small number of trusted developers. But it's not foolproof - they absolutely cannot review and approve every .deb package out there, especially on a nonprofit basis.
And there's nothing in Linux that requires you use this governance structure. Think about how things like Ubuntu PPAs are technically the same anyone-can-sign tragedy that makes npm a hostile environment (even if nobody has attacked them yet). There's also no particular reason why you couldn't ship a Linux distro from a powerful international megacorporation with strict lockdowns everywhere. In fact, that already exists, it's called Android[2].
Of course, you might argue that people should be more literate users and vet the packages themselves, and we should just settle for trust-the-delivery-guy. In the context of the original blog post, which is talking about PyPI packages for developers, that might make sense. But think about how many developers transitively trusted `left-pad` and got burned when that package got pulled. I do think there is room in the developer ecosystem for some non-profit entity that can vet FOSS packages.
[0] In the broadest definition of "censorship". Yes, I know I'm including what the US 1st Amendment would technically consider private counter-speech in there. If we go purely by "only governments can censor" then Steve Jobs Did Nothing Wrong, there's nothing wrong with death threats from Nazis, and Facebook should be allowed to libel actual medical journals with shoddy fact-checking.
[1] That being said, it is more common than you think for malware to disguise itself as pirated apps. If you're already violating copyright, then slipping in some malware doesn't actually increase your legal risk. Thus, blindly enforcing the worst kinds of copyright maximalism actually does sweep away some malware... at the cost of customer-hostile antifeatures everywhere.
AFAIK deliberately signing non-malicious pirated apps would probably open you up to plenty of legal challenges, DMCA 512 notwithstanding, so I'm pretty sure you couldn't provide a "bare guarantee of security" anyway.
[2] Yes, I am aware that Android supports third-party app distribution. However, the OS privileges Google apps in various ways; up until Android 12 you couldn't even auto-update non-Play apps. Furthermore, I personally would not trust most third-party app distributors as the space is extremely sketchy. It's one thing to distribute your own apps outside of Google Play, but becoming an app distributor exposes you to the conflicts of interest I listed in the main part of the post.