[Distutils] PEP draft on PyPI/pip package signing

Giovanni Bajo rasky at develer.com
Mon Jul 28 23:57:45 CEST 2014


Il giorno 28/lug/2014, alle ore 22:26, Donald Stufft <donald at stufft.io> ha scritto: 

> Use GPG for Package Signatures
> ———————————————

Many thanks for reviewing my proposal.

> I have to say, I'm not entirely thrilled by this part of the proposal. I do not
> think it gives us much above what we currently have in terms of security and
> I think it will muddy the waters and potentially prevent implementing a more
> comprehensive solution in the future.
> 
> All of the trust in this proposal flows from a simple trust file. Generating
> and fetching this file is the weak link in this proposal. Generating this file
> relies on PyPI not being compromised and also having a proper state of the
> world. The ways in which this falls down are:
> 
> * Anyone able to defeat our TLS and is in a position to MITM a regular user
>   can simply supply their own trust file.

Yes, though as you say, this is fixed by having the trust file signed. 

It can also be mitigated with certificate pinning and online sign of the trust file. Google+Chrome has shown that pinning is very effective for this specific use-case (specific client connecting to specific server). 

> * Anyone able to defeat our TLS and is in a position to MITM a package author
>   can simply register their own GPG key.

The same happens with PEP458, for all packages but those in the “claimed" role (which requires manual vetting; this can be added to my proposal as well).

This is fixed by 2FA. Notice that implementing 2FA but *not* package signing is not enough to fix this attack; the attacker in fact would still be able to simply modify a package release in the transit, and the user would then 2FA-authorize a modified package without realizing it.

This is one of many examples in which 2FA collaborates with package signing to increase security, and this is why I merged the two proposals; of course they can be split, but together they achieve more.

> * Anyone who has compromised an authors PyPI account can simply register their
>   own GPG key.

The same happens with PEP458, for all packages but those in the “claimed” role. 

This is fixed again by 2FA. With notifications, there is a partial mitigation; delaying 72 hours for popular packages is also a good mitigation. 

For this specific scenario (attacker who has compromised the PyPI account), I agree that package signing is not specifically useful; but it is also expected as a PyPI account is the only way we associate an author with a package, so it makes sense that end-to-end security is broken.

> * Fastly (which is effictively a persistent MITM) could simply modify traffic
>   to register their own GPG key.

True. This is also fixed by PyPI online signing of the trust file.

> * Anyone who has compromised PyPI can simply generate their own trust file
>   with their own keys.

Yes, this scenario is well analyzed in my PEP, including mitigations and likely attack vectors.

I don’t see PEP458 solving this, but this is where my understanding of it gets fuzzier; compromising PyPI let you compromise all online roles, as far as I can tell; and at that point, you can compromise timestamp, consistent-snapshot and recently-claimed roles at the same time (which the PEP states that must be online), and this allows you for serving malicious updates, do freeze attacks and whatnot. 

The only real additional security of PEP458 seems like the manual step of vetting maintainers keys, thus freezing them. If this is a wanted improvement, it can be easily added to my proposal a well with a very slight modification. The hardest part here is how the vet process should work; it’s a VERY complicated process to pull off in the real world without being subject to e.g.: social engineering; if the process is worked out, it’s trivial to modify my proposal to handle this as well. 

> Now it is true that if we sign the trust file with a key that is stored on
> PyPI, then the first one of those cases is no longer possible. However the
> remaining three are still there. This means we are still effectively relying
> on the security of TLS and thus we've not really gained anything except
> additional complexity.

I think you’re oversimplifying the conclusion. There are many possible attack scenarios, and my proposal (as a whole) fixes many of them, as described in my threat model.

Also it looks like you’re also ignoring the additional layer of manually handling a local copy of the trust file. This is very useful for some scenarios like unattended deployments and company indexes, and protects against additional attacks (e.g.: shadowing of private packages in PyPI). I’ve just updated the PEP to describe these attacks.

Can you please explain which of your proposed attacks is better handled by PEP458?

> An additional problem is that as an append only file, this file will end up
> growing unbounded forever. It's not particularly hard to imagine that this can
> cause few problems, especially for new users, who will experience that they
> need to download a multi-gig file before they can download anything. It's also
> trivial to DoS this by simply generating a ton of things that could cause this
> events which need to get written to this file causing it to quickly balloon to
> massive proportions, and because the end clients must treat this file as append
> only there is zero remediation available to undo the damage caused by this kind
> of DoS.

With a conservative average of 60 bytes per package, the trust file would measure around 3 mb today. Assuming all authors rotate GPG keys every year, and package numbers that grow 50% every year, the trust-file would reach 170Mb in 10 years. Introducing a way to reset (“rotate”) the file every 5 years seems more than sufficient.

You have a solid point on DoS, this is something that must be handled through throttling I guess. I don’t see TUF fixing this either; isn’t there a single ever-growing targets.txt?


> Implement 2FA/Better Authentication
> -----------------------------------
> 
> Absolutely, we don't need a PEP to do this, we just need to do it. It's on my
> personal TODO list but other things have had higher priority thus far.

Maybe not a PEP, but some discussion is needed.

Would you prefer patches against PyPI or warehouse? Would you evaluate a simpler solution using a third-party 2FA provider (e.g.: Authy or Duo Security) that could be talked into a PSF sponsorship, or would you prefer an in-house solution? If in-house, is it OK to go with a standard OATH TOTP with QR Code for provisioning, or you prefer to also have alternatives like SMS? How do you propose to handle recovery for a lost token (e.g.: stolen smartphone with no backup)? Would you ask for the token for all web logins? What about package uploads: should distutils be modified to also ask for 2FA in interactive mode on the terminal, to confirm a package release?

I have my own preferred answers to the above questions, but you might have a strong opinion already.
-- 
Giovanni Bajo   ::  rasky at develer.com
Develer S.r.l.  ::  http://www.develer.com

My Blog: http://giovanni.bajo.it





-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4207 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/distutils-sig/attachments/20140728/782ebae2/attachment.bin>


More information about the Distutils-SIG mailing list