-
Notifications
You must be signed in to change notification settings - Fork 1
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
Signed and certified packages #29
Comments
I don't think |
Agree with @kenany. I think this should be handled at the package manager layer. |
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. |
Why can't npm distribute the public key as part of its package, and sign all npm packages with the private key? |
@yurivict In fact I thought about it too, but then I got distracted and never finished the: npm/npm-registry-client#43 |
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. |
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 |
@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. |
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. |
@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 |
This is something we're tinkering with at NodeSource, so pulling @bmeck in here at least so he knows this discussion exists. |
Yarrrr! Brain dump as follows (too tired to go into depth):
Feel free to mention me about various points that are brought up. PS: Just say no to PGP unless you have to. |
While there are plenty of valid criticisms of PGP, it would fit in nicely with Git/Hub's support for PGP. |
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 -> (note, all of this commentary provided courtesy of @dstufft, who runs pypi. I am just a messenger who really cares about this topic). |
@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:
The downsides of PGP, which I think are critical:
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:
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 |
@isaacs I'm afraid you're a bit over-optimistic about SSH keys, at least for your points 1 and 2. GitHub encourages HTTPS use these days, and as such SSH is not part of the workflow for most new users. I did set up SSH one upon a time, and I guess there are some things at https://github.com/domenic.keys, but I don't have those corresponding private keys anymore, since I just use HTTPS. |
Honestly, the mechanism by which a package is signed (GPG, PGP, NaCL, x509, whatever) is probably the least important part of secure signing toolchain. Lots of language repositories have implemented (a) and punted on (b) and (c) and essentially gained nothing. It's my belief that if npm does (a) without a solution for (b) and (c) they'll have gained nothing as well. I don't use Node or npm, so I don't have a horse in this race, I'm just one of @krotscheck's coworkers but I've spent a fair amount of time working on and thinking about this particular problem in general. I'm more than happy to offer advice if it's wanted, but If y'all want to do your thing without it that's fine too. Like I said, I don't have a horse in this race, but am willing to help make a more secure internet. |
The wonderful thing about open source is that you don't necessarily have to provide your own resources, @isaacs. There definitely seem to be enough individuals interested in this feature to solicit the community for help. |
@dstufft Most implementations of (a) that I've seen have never risen to the level of usage required to be relevant. Without a vast majority of people using it, any implementation of (a) doesn't matter much. (b) is solvable to within a pretty reasonable degree of safety relatively easily, though it is some feature work (email the user every time their keys change, require login to add/remove keys). (c) is essentially an unsolved problem in the history of human existence in any context, but somehow we still manage to trust one another enough for society to function, so I'm less worried about it. If we get data about (a) and make (b) reasonable trustworthy, then folks can decide for themselves who they want to trust, and it's not too hard to have a system for defining some kind of policy (with the default being "trust everyone", since that's the only default that can make sense in general for newcomers; if we want to make everyone stop trusting someone, we'd just remove their keys or ban them or whatever). We could get into some kind of Thankfully, there is a for-profit entity that is both aware of these issues and stands to benefit financially from solving them adequately. @domenic Do you have to type your password in to push code to your repos? |
@krotscheck In my experience, relying on that for stuff like this is less effective than you might imagine. Running a keyserver system and managing signatures is a non-trivial task that is fiddly enough to require full-time attention for a while. The bits that are strictly coding are trivial; what's needed is a service run reliably at scale by a widely trusted authority on npm packages, and integration with the npm accounts and website systems. |
No; one uses the git credential helper. |
Fascinating! Another thing worth mentioning here is that, if the user doesn't have an SSH key in the expected location (or available via |
@isaacs I agree - that's why I find the binary transparency effort so interesting, because it comes with two major orgs that are already willing to build the distributed service at a scale that will meet both FreeBSD and Google's demands. The only reason HP hasn't thrown its weight behind it is that I've been busy trying to get our debian boxes to have a recent version of npm :-P |
As a package author, my ideal API would be:
I recommend separating existing npm auth from the new signing private key, so that if one is compromised, the other isn't. I also question using SSH keys for something they weren't intended for. Ideally the signing key is encrypted on disk using a passphrase, with something like AES-256. |
Maybe a simpler API? Complexity is the enemy of security. I'm also a package author, and I would prefer something like:
|
Oh how I wish this were true :]
Not sure if we're on the same page (what is TOFU lol). If the publisher's password (or session token) is validated by registry during
Hmm, again we're on a different page. End-to-end is for encryption, we're only talking about signing. And all this is optional on top of the auth already in place. We shouldn't require people to create and shuffle around secret data keys in order to use npm for simple stuff. |
Good thing it is! 😄
Because that's not at all secure.
Sounds like confusion. E2E just means ... exactly what it says: end-to-end. Signing can be done end-to-end, and signing is encryption. How do you think the signature is generated? It's done using the same asymmetric primitives that are used to encrypt messages. EDIT: yes, signing and encrypting are typically considered different things, but underneath they are effectively the same math being used in different ways, and yes E2E signature validation is a thing. |
sure, signing can be done on a shared secret. but then the trust is not transferable and the signature is only valid for 2 parties. We need signatures that are publicly verifiable or else there is no web of trust possible. |
Signing is not done using a shared secret. It is publicly verifiable. |
it really depends on the protocol's goals but yeah. i'm done here. |
🤢 |
So it is a little disheartening that this has been open for 2 years now. Recent typo squatting of packages with malware that steal secret tokens from environment variables is one good example of why this problem should be solved. If npm supported package signing then it would have been much harder to deploy/install malware infected packages. |
How would package signing prevent people from requesting the wrong package? The malware author could also sign their package. |
@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. |
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. |
@bmeck covered a lot of it so much thanks but I'll also repeat and elaborate. @seldo the scenario would be the user runs It doesn't solve the problem of malware authors pushing signed packages but it does at least allow the end user to be more cognizant and aware where their packages come from and how trusted those users and packages are based on how the packages are signed and how trusted the signing key is in the user's local trust chain and on keybase. Right now it doesn't look like such provisions exist. If I want to verify the authenticity of a package I have to go out of my way by asking the package author to post signatures somewhere where I can verify and then I have to write wrapper scripts for |
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. |
@seldo I'd be happy to discuss if https://github.com/WICG/webpackage might be suitable in their repository issues. |
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 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). |
@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. |
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. |
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 :)? |
@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 |
@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? |
nevar 4get eslint/eslint-scope#39 |
@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 |
@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. |
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.
The text was updated successfully, but these errors were encountered: