Skip to content

Package Signing Survey #5

Open
Open

Description

@iarna

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.

Activity

  1. ewdurbin commented on Jan 21, 2018

    @ewdurbin

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

  2. steveklabnik commented on Jan 21, 2018

    @steveklabnik

    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

  3. riking commented on Jan 23, 2018

    @riking

    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
  4. tsibley commented on Jan 23, 2018

    @tsibley

    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.

  5. larsrh commented on Jan 23, 2018

    @larsrh

    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.

  6. justincormack commented on Jan 23, 2018

    @justincormack

    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.

  7. paragonie-scott commented on Jan 23, 2018

    @paragonie-scott

    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.

  8. bmeck commented on Jan 23, 2018

    @bmeck

    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.

  9. vladimir-v-diaz commented on Jan 23, 2018

    @vladimir-v-diaz

    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.

  10. danielcompton commented on Jan 23, 2018

    @danielcompton

    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.

  11. Daniel15 commented on Jan 23, 2018

    @Daniel15
    Member

    cc @hach-que (who created pkgsign)

  12. iarna commented on Jan 24, 2018

    @iarna
    MemberAuthor

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

  13. kentfredric commented on Jan 24, 2018

    @kentfredric

    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.

  14. ehashman commented on Jan 24, 2018

    @ehashman

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

  15. rido-min commented on Jan 24, 2018

    @rido-min

    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.

  16. hach-que commented on Jan 24, 2018

    @hach-que

    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.

  17. tsibley commented on Jan 24, 2018

    @tsibley

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

  18. aef commented on Feb 2, 2018

    @aef

    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

  19. nealmcb commented on Sep 16, 2019

    @nealmcb

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions