Skip to content

Signed and certified packages #29

Open

Description

@Ginden

It should be possible for require function to validate required packages for their security.

Assume I'm running company that uses io.js for something important. We can't allow our programmists to use potentially dangerous (because of author pushing malicious package to npm or something) packages. These packages can be hidden deep in package dependencies.

I think it should be allowed to certify ("We, Code Review Company, guarantees it's valid and secure package") and sign packages using PGP keys. Moreover - it should be possible to have parameter (flag?) that allows requiring only safe packages (we have theirs public keys) and throws error when something requires potentially dangerous package.

It can result in increased adoption of io.js as trustworthy platfom.

Activity

  1. kenany commented on Jan 16, 2015

    @kenany
    Member

    I don't think require should be in charge of this. This seems more like an issue for npm, and in fact there are a couple of entries on the issue tracker regarding this (the integrity part of your request, at least): npm/npm#3252, npm/npm#4016.

  2. ruimarinho commented on Jan 18, 2015

    @ruimarinho
    Member

    Agree with @kenany. I think this should be handled at the package manager layer.

  3. othiym23 commented on Jan 19, 2015

    @othiym23

    In fact, if you use npmE (and I'm sure there are other private registries and registry proxies that support this), there are already whitelist and blacklist features that give teams control over which packages can be used in their projects, set up in such a way that no packages that aren't on the approved list can even be installed within a protected intranet.

    There have indeed been requests and proposals to come up with a general mechanism for package signing, and the main barrier there is the usual problem of how to authenticate signed packages without creating a usability and security nightmare. I think doing it at the package level is appropriate, though, because anything that's cryptographically secure is going to impose CPU overhead that's ridiculously high in the context of bringing up a web service in production.

  4. yurivict commented on Mar 16, 2015

    @yurivict

    Why can't npm distribute the public key as part of its package, and sign all npm packages with the private key?

  5. indutny commented on Mar 16, 2015

    @indutny

    @yurivict In fact I thought about it too, but then I got distracted and never finished the: npm/npm-registry-client#43

  6. mbonaci commented on Mar 16, 2015

    @mbonaci

    Of course you can, but it's not in his employer's interest to do so, so he'll keep slipping you enterprise version and packaging the potential implementation in nightmares.
    What about NPM foundation?

  7. yurivict commented on Mar 16, 2015

    @yurivict

    I asked about package authentication here https://www.npmjs.com/support and here npm@npm.org, but can only hear this as an answer: https://www.youtube.com/watch?v=Re72di5phM0

  8. othiym23 commented on Mar 16, 2015

    @othiym23

    @isaacs, @seldo, and I have discussed adding package signing to npm, and have some tentative ideas about how it should be designed (probably more likely built on ssh keys than OpenPGP / GnuPG, for many, many reasons), but getting to that is a ways out, and is probably a ways behind getting more robust authentication to the registry.

  9. yurivict commented on Mar 16, 2015

    @yurivict

    pgp is good for e-mail. But in respect of package signing, it depends what is meant here. If you are going to download pgp key from the public pgp server, this is also a security threat.

  10. timkuijsten commented on Mar 17, 2015

    @timkuijsten

    @othiym23 maybe signify(1) is something usable. I know it's used with pkg_sign(1) and is licensed under ISC. See it's announcement from last year: http://www.undeadly.org/cgi?action=article&sid=20140121114349&mode=expanded&count=0

  11. rvagg commented on Mar 18, 2015

    @rvagg

    This is something we're tinkering with at NodeSource, so pulling @bmeck in here at least so he knows this discussion exists.

  12. bmeck commented on Mar 18, 2015

    @bmeck

    Yarrrr! Brain dump as follows (too tired to go into depth):

    1. Developers hate signing things, we need to use keys that they already have. I have spoken to several people about this and I think _ssh keys_ are winning. Many different kinds of keys can even be used by reused as ssh keys which is a win.
    2. Having require perform code signing on a per require basis is a bad idea, you want to perform the analysis on the whole of what you require, thus we would want signatures to be associated with the whole module tree (difficult without moving to archive files ala noda-loader. I am currently speccing out getting the loader to do signing, but have not gotten around to making anything
    3. There are multiple points where signing is important as noted in this doc. We can associate module signing with some things, but signing an application in the same manner would most likely prove difficult since we generally want to associate with a certificate chain from the people I have talked to.
      1. There are also multiple definitions of deployable targets; we can ship a full archive of the compiled source, and there are several tactics to create single binary files. Our signing process should stay limited to the archives and leave binary signing to the tool of choice for the target os/arch.
      2. There is also a question of how to approve keys for usage, revocation lists might need to become prevalent and that is something that no one enjoys.
      3. There is a question about signing via groups, for example if a audit group signs modules as having been audited. To do this we would need to define our CA setup more in depth than just via keys.
    4. IO.js and Node.js dist use pgp keys.

    Feel free to mention me about various points that are brought up.

    PS: Just say no to PGP unless you have to.

  13. indolering commented on Sep 7, 2015

    @indolering

    While there are plenty of valid criticisms of PGP, it would fit in nicely with Git/Hub's support for PGP.

  14. krotscheck commented on Sep 30, 2015

    @krotscheck

    A couple of things re: PGP vs. SSH.

    The difference between the two is that they use a different container format - inside of that container, the key is going to be something like RSA, ED25519, etc. Which container is used is mostly irrelevant at that point, though you'll get into a bit of a religious war if npm forces one over the other.

    The much harder part is determining what the trust model is going to be. Signing and keys are easy, figuring out whether those signatures can be trusted is hard. There's an excellent blog post here ->
    https://caremad.io/2013/07/packaging-signing-not-holy-grail/ that talks about different approaches. Also, there's an effort being spearheaded by Google called Binary Transparency that tries a somewhat different approach altogether - involvement in that starts here: https://groups.google.com/forum/#!forum/binary-transparency

    (note, all of this commentary provided courtesy of @dstufft, who runs pypi. I am just a messenger who really cares about this topic).

  15. isaacs commented on Sep 30, 2015

    @isaacs

    @indolering I am not swayed by Git's support for PGP. While git does an admirable job of making it Just Work, as long as you have your keys set up, etc., the dearth of signed commits and tags in GitHub (and signed packages in rubygems) should indicate that it's not easy or usable enough to be considered a valid approach.

    @krotscheck Thanks for the links.

    We don't need a holy grail, and I agree that we should not try to claim that package signing is one. We do need an approach that will be (a) usable enough to enable it by default without disrupting our users, and (b) given relatively high adoption rates, increase the security level enough to justify the cost of implementation. Ideal security is less valuable, in aggregate, than ideal usability, and less attainable.

    There's a lot to admire about PGP:

    1. It doesn't pretend at perfect security. It's "pretty good protection", which can be then used to bootstrap other techniques to strengthen the trust in the key set. (Webs of trust, signing individual files, etc.)
    2. It's got a nice vocabulary of "stuff you can do with keys". Encryption for a specific recipient, signature by a known source, etc.
    3. Just removing a key from the set of trusted keys has the side-effect of invalidating everything signed with that key. So it's a nice kill-switch.

    The downsides of PGP, which I think are critical:

    1. No one has PGP set up. Ok, a few people do, probably a lot of them on this discussion thread, but seriously, it's a rounding error away from no one. The difficulty of getting it set up and working is too high for the vast majority of publishers, and even higher for the vast majority of installers, so what's the point?
    2. PGP tools don't exist for Windows. About half of all Node users are doing their development on a Windows machine.

    I was once hopeful Keybase.io might move the needle a bit on this. It hasn't. Unless it's trivial for 99% of publishers, and at least 80% of installers, there's no point. So PGP is out, at least for signing npm packages.

    SSH keys are a bit less convenient to work with from the installer's pov, since there isn't as clear a vocabulary of actions and use cases. However:

    1. Everyone using GitHub already has SSH keys on their system.
    2. GitHub is already a public repository of public SSH keys. https://github.com/isaacs.keys So we can pretty trivially import them. (And if those keys get pwned, you're dead anyway, so who cares?)
    3. SSH keys work on Windows.
    4. We have in Node.js all the same crypto APIs to do what we need, and it's Just Typing to get to all the same benefits we would have with PGP.

    I would really like to separate the problems of (a) "this artifact was definitely published by a user presenting this specific key" from the problems of (b) "which keys belong to this user" and (c) "which users should I trust". These problems are all orthogonal, and "package signing" can really only solve (a), and the challenge is to do so in such a way that doesn't make (b) and (c) impossible.

    Before we (ie, npm, Inc.) invest resources in this, we need to finish shipping the products that will keep our lights on so that we continue to have a registry worth securing ;) I expect that this will be a revenue blocker soon enough, however, because it's a thing that big enterprise shops care a lot about, and then I can justify putting resources behind it. My best WAG is probably some time in 2016 it'll get started in earnest, and then a year or so after deployment it'll be in widespread usage enough to start getting obnoxious about packages that are unsigned.

    Back to the point of the OP here: This will probably never be something worth doing at the require() level. We're all really talking about signing at npm publish time, and verifying at npm install time, and there are a lot of usability barriers that might crop up once we start actually doing it.

  16. 17 remaining items

  17. seldo commented on Aug 4, 2017

    @seldo

    How would package signing prevent people from requesting the wrong package? The malware author could also sign their package.

  18. bmeck commented on Aug 4, 2017

    @bmeck

    @seldo depends on verification setup. If it is done at install time you can have a more aggressive check of expiration/revocation lists/OCSP. If it is done at startup time you might still want to do this.

    As per prompts of accepting packages; just like SSH, if something is signed with an unknown key you can get a prompt. Most people unfortunately will just accept the key, even as a developer who might have some security knowledge. However, for production scenarios you could completely disable this to a list of known keys. This allows a whitelist on the client rather than just on the registry.

  19. bmeck commented on Aug 4, 2017

    @bmeck

    Plus side of known cert approval is that if a new transitive dependency appears from an unknown source it would be picked up very quickly.

  20. seldo commented on Aug 4, 2017

    @seldo

    Thanks both for elaborating.

    npm is doing design work around signed packages, but our near term security work is around 2FA to prevent unauthorized publishes with stolen credentials, as well as a lot of different new strategies for detecting spam and malware and taking them down faster.

  21. bmeck commented on Aug 4, 2017

    @bmeck

    @seldo I'd be happy to discuss if https://github.com/WICG/webpackage might be suitable in their repository issues.

  22. dstufft commented on Aug 4, 2017

    @dstufft

    Please note, I am not a Node.js user, but I do work on similiar packaging tooling so I've thought about lot of these issues!

    TOFU like with SSH doesn't work great for package managers, because with SSH you generally connect to a small set of stable servers that you know ahead of time. So your list of ~/.know_hosts rarely changes and if you add new administrators the host key for the server stays the same.

    This is unlike packages, where you're often times installing packages you've never installed before, and your packages are likely going to depend on things that you don't directly know ahead of time that it's going to pull in. Further more this list is constantly changing which makes it even harder to manage a TOFU trustdb. Finally since you're attempting to validate authors not a per-package key, if you have two authors both able to release software, suddenly the person through a normal course of installing software has to deal with invalid signatures. A TOFU database tends to normalize end users needing to just go ahead and add whatever key they need to to the trust store, without really digging into or thinking about what they're doing (because it is a normal day to day operation for them at that point).

  23. bmeck commented on Aug 4, 2017

    @bmeck

    @dstufft I agree on developer machines to a limited extent if the TOFU db never gets checked against mechanisms for revocation. Installing on a build server can be much more limited and have safety on that side. We can discuss trust models if desired but I am personally for X.509 style trees rather than web of trust when discussing revocation.

  24. dstufft commented on Aug 4, 2017

    @dstufft

    Revocation doesn't really work very well TBH, most browsers don't even bother to support certificate revocation anymore (well they've started shipping revocations built into the browser itself, but only for important certificates). The issue comes down to the fact an attacker can just block the revocation check and then you have to decide to hard fail or soft fail. If you hard fail then your revocation becomes a SPOF and if you soft fail then revocation is trivially defeatable. You can see more information about that here: https://www.imperialviolet.org/2012/02/05/crlsets.html

    I do agree that x509 trees are better than web of trust. In Python we're planning on implementing TUF and I recommend using that. You still need to decide how specifically to manage trust, but it's pretty solid tech.

  25. frio commented on Feb 13, 2018

    @frio

    conventional-changelog/conventional-changelog#282 has had an impact today. In this instance, the damage was limited to an easily expunged crypto-miner; across an organisation (especially one with an NPM cache), this is difficult to track down but not devastating. If this had been a cryptolocker alternative, this could have been devastating for a lot of people. Where is the work to implement 2fa or signing tracked :)?

  26. bmeck commented on Feb 13, 2018

    @bmeck

    @frio I'd watch https://github.com/WICG/webpackage (it has a long outstanding name change request) which should be applicable across Web, Electron, and Node. There exists a separate efforts at a purely package manager level and not for loader checks in package-community/discussions#5

  27. sashahilton00 commented on Jun 26, 2018

    @sashahilton00

    @isaacs is there any update on this? I note that you mentioned in September 2015 that you guessed we might see it rolled out in 1-2 years, and whilst it was only a guess, we're nearing the 3 year mark for this issue with no apparent end in sight. Is it even on the roadmap anymore?

  28. kmoe commented on Jul 12, 2018

    @kmoe
  29. carlos8f commented on Jul 12, 2018

    @carlos8f

    @sashahilton00 @kmoe @isaacs @bmeck i can do a PR that incorporates Salty(https://github.com/carlos8f/salty) using Daniel J Bernstein's libsodium. it's the most bulletproof future-proof crypto that is public domain in existence, and its a shame that no one is using it. it's my life mission to spread Daniel's work around and make encrypted, signed, and verified data the standard, instead of the exception. Daniel understands that most crypto is backdoored, including all NIST-published curves, and this has been proven in writing and with equations by Schneider et al. The only usable curves are those that Satoshi chose and that Daniel chose, the others are phonies and are being spied on and NSA'd.

    Let's incorporate Salty as the way to easily sign an npm package. i can do the PR in a day. all i need is ppl to agree with me and start using Salty. I am working with Satoshi right now on Bitcoin next gen, which will have full encryption and privacy via Salty. So take it or leave it :) it was over 2 years ago that i wrote Salty and so far no one is hip enough to apply it. Im here to change that.

    https://s8f.org/1463990203
    https://s8f.org/1465262642
    https://s8f.org/1465282150
    https://s8f.org/1466743328

  30. strugee commented on Jul 12, 2018

    @strugee

    @carlos8f the crypto parts of this are the least hard to do. It's everything else that's the problem. You should read this issue all the way through.

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