Open iarna opened 6 years ago
Sounding off for PyPI here :)
Until https://github.com/pypa/pypi-legacy is retired with the deploy of https://github.com/pypa/warehouse, implementing The Update Framework (TUF) is effectively stalled.
The long term goal is to deploy TUF for PyPI and eventually begin implementing verification in clients. It has just been deemed too complex for deployment while we are simultaneously running two codebases... one with no tests :)
crates.io doesn't do any signing yet. There's been a few proposals, as you've mentioned above, TUF was one of them. There's also this one: https://github.com/rust-lang/cargo/issues/4768
Obvious mention to Debian package signing ("SecureApt", not in-deb signatures).
The index file (Packages
and Packages.gz
) contains checksums of every package file, and then the index is signed using detached GPG (Packages.gpg
).
Weaknesses:
Strengths:
Regarding Perl, there are also CHECKSUMS
files for every author's directory on CPAN, e.g. https://cpan.metacpan.org/authors/id/T/TS/TSIBLEY/CHECKSUMS. These are maintained by PAUSE, the canonical indexer for CPAN, using the CPAN::Checksums module. Every CHECKSUMS
file is also signed by a yearly-updated PAUSE key.
Module::Signature is good, but even for packages that don't use it, the CHECKSUMS
file ensures you have the same thing that PAUSE indexed and that CPAN mirrors or MITMs haven't tampered with it.
Regarding the Scala/Java ecosystem: The vast majority of Scala developers uses sbt as a build tool. sbt is capable of consuming and producing Java/Maven-compatible artifacts. While in principle there's no "authoritative repository" of artifacts, most are usually published to Maven Central.
That repository requires PGP signatures of artifacts (example). Trying to upload an unsigned artifact will fail.
Signing requires set up of a PGP key pair and configuration of the build tool (the former of which is quite hard for newbies, the latter is sort of manageable, because there are plugins that do it).
However, there's no requirement to announce the PGP keys used to sign artifacts, so there's also no good way of retrieving them for checking. Hence, sbt (I can't speak for other build tools) doesn't bother to check the signatures at all. In the case of sbt, it is possible to check signatures, but you'll have to rely on the keys being either in your keyring or available from some keyserver.
While Docker is not yet turning on TUF signing by default for all users, we are rolling out better UI to make this easier, aiming to enable it for official images sooner, and it is used by enterprise Docker customers via the integration in Docker EE. We also use it in projects like LinuxKit.
TUF is also shipping in embedded applications such as automotive. The OCaml community is also looking at it for their package manager see https://opam.ocaml.org/blog/Signing-the-opam-repository/
It is definitely non trivial to roll out universal signing. @JustinCappos can definitely help out with TUF.
This is something I'm planning on bringing to the PHP community by improving the Composer package manager.
I've previously suggested it to WordPress but they seem dead set on never committing a second of core developer time to that ticket. I rewrote libsodium in pure PHP partly to solve this problem for the WordPress community and that still wasn't sufficient for them to care about protecting their users from supply-chain attacks.
I developed a competitor CMS called CMS Airship that used Ed25519 to sign packages and checks all updates into a Merkle tree so users can verify that everyone is getting the same thing (mitigates silent, targeted attacks).
Finally, in the same vein, our paid security product (TL;DR web app firewall) also includes automatic updates which enforce package signing, signed by our company. This will, for example, keep your Magento sites up-to-date on the latest security patches automatically.
WebPackage contains a method being standardized for HTTP payloads that are packages for browser consumption and node compatible loading. I'm not sure the mechanism is universally applicable to a package manager with separate install and access phases, but it has a lot of details about trust for both the offline use case and direct integration with browsers.
The Update Framework which has seen a lot of discussion of implementing it (the Python PEPs above, Haskell, Rust), but as far as I can tell only Docker has actually shipped it, and even then it's disabled by default.
Flynn.io has deployed TUF. Secure updates with LEAP's Bitmask application.
The following videos might be of interest, they do a good job of covering their respective experiences with TUF.
For a long time Clojars had a repository which required GPG signing of packages. We removed this in late 2015, as there were no meaningful security benefits to the GPG signing process we had in place without a wider web of trust for people to rely on, and the overall process confused people.
I'd very much like to see something like TUF adopted in the Maven ecosystem. I opened this issue on the Clojars repo and discussed it on the Clojure mailing list, but there wasn't a great deal of interest.
cc @hach-que (who created pkgsign)
@tsibley When are checksums for those indexes validated? IIRC, the cpan
commandline downloads a copy of the index, does it validate then? Obviously cpanm
doesn't and has to trust meta::cpan. Do you know if meta::cpan have a process for validating these signatures?
@vladimir-v-diaz Flynn does not seem to be a language package manager? That would mean it's out of scope. TUF has been implemented for a bunch of things, but I would like to keep the discussion here more focused. The same applies to Bitmask.
Because its common enough for people who author packages to mess up to the point they ship with invalid signature data, and not notice, enforcement of Module::Signature based signatures is an opt-in mechanic.
Similarly, due to periodic outages and anomalies in the mirror network where the archive replicates, but the signatures do not, enforced signature checking of the checksums created by PAUSE are also elective, and opt-in.
cpanm
can be used to opt-in to both of these via cpanm --verify
.
No "trusting" of Meta::CPAN is necessary.
Any servers cpanm
fetches from are just replication mirrors, which uses the PAUSE-signed integrity checks, so the sources of trust still resolve back to either the PAUSE upload server, or to the author themselves, depending on which integrity checks you use.
I personally employ the --verify check as standard practice in my cpanm wrapper, and its usually fine, but it causes occasional inconveniences due to false-failures do the reasons stated above ( they're false failures in that their integrity testing failed, but investigation turned out that the failures themselves were inconsequential, and the result of either network phenomena or contributor error )
In general though, package-internal integrity checks are an annoyance, not least because you have to decompress the tarball to simply check the signature. But also, any packages that do "self-testing" for signatures introduce paths of failure, which pose annoyance for downstreams when we need to patch an unmaintained package, or in other cases, potentially adding dependencies that aren't wanted or useful, and resulting in substantially more code executing which results in more places for things to get broken ( For example, if Module::Signature depends on say, Math::Pari, and Math::Pari stops working on a future Perl, then your otherwise fine code ceases to function on a newer perl when integrity checks are not trivially avoidable )
However, in my understanding of CPAN, there is nothing to stop somebody developing an uploading system that generates external signature files for submitted archives, and uploading those signature files independently. ( PAUSE itself functions largely as a "you're allowed to upload -> you can upload anything" server, where the concept of "indexed" only applies to things that are obviously usable perl packages. Non-perl files are frequently uploaded and PAUSE faithfully uploads them and they get mirrored, just nothing special happens wrt "cpan install foo" )
If somebody developed such a system and it gained traction, I'd imagine it wouldn't be much work to add official PAUSE support for them after the fact and use them as additional submission validation criteria.
I don't see a mention of it here, so I'll add that Java comes with a suite of various security tools built in that allows developers to sign jars: https://docs.oracle.com/javase/8/docs/technotes/guides/security/SecurityToolsSummary.html
(It is complicated to pull off, and managing the Java keyring is extra overhead, so I normally PGP-sign jars and distribute them with an ASCII signature, similar to what Clojars used to do.)
NuGet is adding Package Signing, we are starting with Author Signatures, and then we will add Repository Signatures. All based on X509 and PKCS7.
Visual Studio and NuGet.exe verifies signed packages on install and restore operations. The feature is already live in our nightly build and preview channels.
Not sure how much useful input I'll be able to give here, other than maybe a quick overview as to how pkgsign works.
It's currently designed to be a package signing / verification system that works without requiring changes to registries in order to support, and makes use of keybase.io and PGP in order to sign packages. Although primarily aimed at JavaScript on NPM/yarn, you can technically use it with any package format you like. The core mechanism that is uses is a signature.json
file in the root of the package, which contains a signed hash of all files expected in the package, and identity information where the public PGP key can be found to identify the signer.
@iarna Basically what @kentfredric said: you opt-in with your CPAN client. cpanm
uses --verify
, cpan
uses the check_sigs
option. The mirrors just sync files, they aren't smart.
There was also an OpenPGP-based alternative to the X.509 default system in RubyGems. Grant Olson provided a CA in the web of trust for a while, but sadly there was almost no one using it and sometime later he shut it down. Here's the code: https://github.com/grant-olson/rubygems-openpgp
It seems worth noting in the Java world that Android packages come as APK files. The format is based on JAR files (an extension of the ZIP file format, with manifests and signatures). APK Signature Scheme v2 added support for the elliptic curves NIST P-256, P-384, and P-521, along with rollback protections and some other things.
I'm not sure what signature requirements the Google Play Store has these days, but they might be relevant.
I'm going to use this issue to make a survey of package signing implementations for language package managers across languages. I'd be interested in hearing both about implementations I'm unaware of and folks experiences in using them.
Module signing implementations, limited to either discussion or those endorsed in some way by the package manager or repository:
Third party implementations: (these are things created within the community that have not been adopted by the package manager or repository)
Special mention to: