Initial implementation of The Update Framework (TUF) for RubyGems

Hello there everyone!

Here at Square we’ve been doing a Hack Week project to improve the
security
of RubyGems. We have been basing our efforts off a software update
framework called The Update Framework (TUF) which is based off work done
to
secure the update system used by Tor:

https://updateframework.com/projects/project

We’ve been working with the TUF team who is already doing similar work
to
secure Python’s PyPI in addition to creating a prototype implementation
for
RubyGems. You can read about their PyPI work here:

https://github.com/theupdateframework/pep-on-pypi-with-tuf

We’ve opened a PR against RubyGems with our initial client-side work. A
PR
against RubyGems.org/Gemcutter with the server-side work is forthcoming.
You can view the initial PR here:

https://github.com/rubygems/rubygems/pull/719

We also have a mailing list specific to this project if you’re
interested
in contributing:

https://groups.google.com/forum/#!forum/rubygems-tuf

(reducing Cc:)
What does this change for existing publishers of RubyGems?

My main concern is keeping the publishing of gems on RubyGems.org an
option for somebody like Satoshi Nakamoto of Bitcoin.

Do u mean: I just want a guide about “how to publish gems by TUF”? Maybe
it will more readable by question like this.
> by the way, I don’t know the answer. a fresh man here, :slight_smile:

On Mon, Nov 25, 2013 at 6:47 PM, Eric W. [email protected]
wrote:

(reducing Cc:)
What does this change for existing publishers of RubyGems?

Great question! For that we need a deeper dive into how TUF manages
“targets” and how that would apply to the existing system. TUF has a
long-lived targets.txt file that delegates to three roles for managing
targets. Here’s what they’d mean for RubyGems:

  • unclaimed: Gems which haven’t been signed by their developers.
    Think
    of this like how RubyGems works today plus a signature by an online
    key
    known by Gemcutter. Not great but better than nothing. This is also
    how you
    grandfather in old gems.
  • recently-claimed: Gems signed by developers whose keys have been
    signed by an online key known to Gemcutter.
  • claimed: Gems signed by developers whose keys have been signed by
    a
    threshold (e.g. the “2-man system”) of RubyGems maintainers in an
    offline
    process which is resistant to key compromise. Gems in “claimed” are
    preferred over gems in “recently-claimed”, so if Mallory breaks into
    Gemcutter and says “I own rails!” and manages to publish a
    recently-claimed.txt specifying this, RubyGems clients would still
    only
    trust the keys listed in claimed. The hope is that most popular gems
    wind
    up in this category which provides the highest security level.

IMO one of the neatest things TUF provides is a way for people to opt in
to
signing gems in a meaningful way without forcing any changes in the
present
workflow. People who don’t want to use TUF don’t have to. They’ll just
miss
out on the security benefits it offers.

On Mon, Nov 25, 2013 at 9:08 PM, Eric W. [email protected]
wrote:

On a side note, have you considered a simple TOFU (trust-on-first-use (or
seen)) system to detect corruption/altered packages? Basically just a
git repository which stores the checksum of any gem which hits
RubyGems.org and is mirrored by many clients. A fetch failure/conflict
would mean something is amiss.

If that’s all you want, there’s this Bundler feature request to keep
track
of a checksum per gem:

https://github.com/bundler/bundler-features/issues/27

Tony A. [email protected] wrote:

People who don’t want to use TUF don’t have to.

OK, good :slight_smile: Because I don’t want people trusting me or my signature.
I could be forced to make it at gunpoint, or I am really just evil >:)

On a side note, have you considered a simple TOFU (trust-on-first-use
(or
seen)) system to detect corruption/altered packages? Basically just a
git repository which stores the checksum of any gem which hits
RubyGems.org and is mirrored by many clients. A fetch failure/conflict
would mean something is amiss.

Hell, while writing this, I wonder if RubyGems index could just be
pulled via git. Might be expensive-as-hell on the server-side if using
git:// or smart HTTP, though.