Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Package Signing Survey #5

Open
iarna opened this issue Jan 20, 2018 · 19 comments
Open

Package Signing Survey #5

iarna opened this issue Jan 20, 2018 · 19 comments

Comments

@iarna
Copy link
Member

iarna commented Jan 20, 2018

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:

  • Perl: Module::Signature. Additionally hashes of all modules are in a signed index.
  • Python: PEP-458 PEP-480, deferred until pypi-legacy is retired.
  • Ruby: Gem::Security discussion
  • Docker: Content Trust (disabled by default, follows TUF, awaiting UI update).
  • Rust: Non-TUF, TUF. Non-TUF proposal on the grounds that TUF requires central authority and does not mandate signing.
  • Scala/Java: with Maven Central, PGP required to publish, but verification not required, trust mechanism not established.
  • PHP: Proposal / Discussion for Composer
  • Clojure: Clojars previous had GPG signing but it was removed due to a lack of a facility for full verification. There has been discussion of modeling something new on TUF.

Third party implementations: (these are things created within the community that have not been adopted by the package manager or repository)

Special mention to:

  • The Update Framework which has seen a lot of discussion of implementing it (the Python PEPs above, Haskell, Rust, OCAML), but as far as I can tell only Docker has actually shipped it, and even then it's disabled by default.
  • Debian APT, uses signed index of checksums, similar to Perl (or vice-versa).
  • WebPackage proposals have headers with signatures for individual copies. If I'm reading this correctly, these follow the CA model that SSL uses.
@ewdurbin
Copy link

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 :)

@steveklabnik
Copy link

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: rust-lang/cargo#4768

@riking
Copy link

riking commented Jan 23, 2018

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:

  • Requires single-file package distribution
  • Traditionally, although it is used to distribute source files, compiled binaries and their supporting files (documentation, headers, config files) are the more common usage.
  • GPG, but this could obviously be trivially replaced with plain elliptic curve signatures
  • Requires full download of index file to verify checksums. Mitigated by local and distributed caching of index file, and most installations use a significant portion of the index.
    WARNING: To avoid delayed-upgrade attacks, the signature file should be retrieved from a high-trust archive over HTTPS. The signature of an outdated index won't validate.

Strengths:

  • Widely deployed with large install base
  • Fairly simple implementation, once you get over the GPG difficulty hump

@tsibley
Copy link

tsibley commented Jan 23, 2018

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.

@larsrh
Copy link

larsrh commented Jan 23, 2018

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.

@justincormack
Copy link

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.

@paragonie-scott
Copy link

paragonie-scott commented Jan 23, 2018

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.

@bmeck
Copy link

bmeck commented Jan 23, 2018

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.

@vladimir-v-diaz
Copy link

vladimir-v-diaz commented Jan 23, 2018

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.

@danielcompton
Copy link

danielcompton commented Jan 23, 2018

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.

@Daniel15
Copy link
Member

cc @hach-que (who created pkgsign)

@iarna
Copy link
Member Author

iarna commented Jan 24, 2018

@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.

@kentfredric
Copy link

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.

@ehashman
Copy link

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.)

@rido-min
Copy link

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.

@hach-que
Copy link

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.

@tsibley
Copy link

tsibley commented Jan 24, 2018

@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.

@aef
Copy link

aef commented Feb 2, 2018

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

@nealmcb
Copy link

nealmcb commented Sep 16, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests