Skip to content
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

Require MFA for most-used gems #35

Closed
jchestershopify opened this issue Nov 16, 2021 · 6 comments
Closed

Require MFA for most-used gems #35

jchestershopify opened this issue Nov 16, 2021 · 6 comments

Comments

@jchestershopify
Copy link
Contributor

Introduction

MFA is an ongoing subject of work for Rubygems, and for good reason. Research has shown[0] that account takeovers are the second-most common form of attack on software package repositories (after typosquatting). As a class of countermeasures, MFA is the best single way we have to reduce the probability of account takeovers.

We are not alone in facing this difficulty. Most notably, NPM has had a recent high-profile spate of takeover attacks on popular packages, which were only detected because of errors in the embedded exploit code. Other cases may well be undetected in the wild.

Yesterday, NPM folks announced that they will make MFA mandatory for "a cohort of top packages":

... we will begin to require two-factor authentication (2FA) during authentication for maintainers and admins of popular packages on npm, starting with a cohort of top packages in the first quarter of 2022. We are currently evaluating next steps to ensure that the strongest and most user-friendly authentication options, such as WebAuthn, are available and accessible to developers using npm.

I think Rubygems should follow this precedent.

Some Implementation Questions

I recognise that it's not as simple as flipping a toggle, or even doable in a single PR. But I believe we should at least aim for this policy and take incremental steps towards it.

Some problems that need to be solved for this to become a policy:

  • Which gems are selected for the policy? Top n-thousand most-downloaded?
    • What about highly-downloaded gems for which there has been no login in a long time?
  • When is the policy enforced? At login? At push?
  • How do we deal with the CI/CD usecase, for which human intervention is often seen as undesirable?
  • Do we need to finish WebAuthn support first, so that those using USB tokens and biometric tokens are covered?
  • How is the policy announced? Blogpost? Email to owners of selected gems?
  • When would the policy take effect?
  • Should the policy be rolled out in phases? Eg. simple nagging at first, followed by hard enforcement later?
  • Should the policy be rolled out in stages? Eg. top 10 gems, then top 100 gems, and so on?

Next steps

The team I belong to at Shopify would like to develop an RFC for this policy change. We are enthusiastic about raising the MFA bar for Rubygems and we'd be prepared to do a lot of the technical work in support of an accepted RFC.

[0] See Towards Measuring Supply Chain Attacks on Package Managers for Interpreted Languages:

We categorize malware by their attack vectors in Figure 8a, which shows that typosquatting is the most exploited attack vector, followed by account compromise and publish. [emph added]

@duckinator
Copy link
Member

I think this is a really good idea, and I'm happy to help when I can (with the caveats that I don't know a lot about security-specific stuff and am only doing ~8 hours/month of work on RubyGems/Bundler at the moment).

Given that (as you mentioned) human intervention is typically viewed as undesirable for CI/CD, I think this winds up intertwined with rubygems/rubygems.org#2755 ("More restrictions on API keys").

Specifically, I think we will need the following for an RFC of this sort to fully resolve the problems it sets out to fix:

  1. Ability to limit API keys to specific gems.
  2. Ability to limit API keys to specific actions (e.g. push-only keys for CI/CD).
  3. Ability to disable MFA/OTP for specific API keys (e.g. for automated releases).

It's unclear to me how much these are intertwined with what you're suggesting, but I don't think we can realistically enforce MFA as a requirement until we allow automated releases despite MFA being enforced. Sadly, the only way I know of doing this is by adding an exception for automated releases, which needs 1 and 2 to minimize the damage in case a MFA-disabled key is leaked.

If you have any resources on how to do automated releases with MFA of some sort, I'd love to learn more about it!

@jchestershopify
Copy link
Contributor Author

jchestershopify commented Nov 17, 2021

I agree that in the short term we need to provide a narrow-as-possible exception for CI/CD cases. We'll include a section in an RFC laying out those requirements as part of flipping on mandatory MFA.

In the longer term I have a vague sense that a two-step process will allow CI/CD systems retrieve single-use tokens from rubygems.org, which are then handed to relevant build steps. That way the business of authenticating can be separated from user-configurable build steps. In OAuth this is done with refresh tokens being used to retrieve access tokens -- the build could only get the access token, not the more-valuable refresh token.

Github provides something that appears similar but slightly different: they will attest a build's workload identity to cloud providers, who then provide a single-use token for that build. It appears to be distinct from the OAuth refresh token flow, and has the advantage that there's no long-lived refresh token to protect. The downside is that it only really works for CI/CD that's managed as a SaaS, because rubygems.org would need to explicitly trust the origin of the attestation about workload identity. It would probably be easy to cover Github and Gitlab with some polite nagging, but then there's a long tail of CI/CD SaaSes and private build systems that would be left in the cold.

@jenshenny
Copy link
Member

+1 to improving and adding more restrictions to API keys outlined in rubygems/rubygems.org#2755.

In parallel to enforcing MFA on most-used gems, I believe we should also start requiring (or at least encourage) new accounts to have MFA setup during the sign up process as for the long term, it would be best that all accounts have MFA enabled.

@jchestershopify
Copy link
Contributor Author

Good point, we should frame it as "cases where MFA is required": top gems, new accounts and to create new gems.

@qrush
Copy link
Member

qrush commented Nov 24, 2021

Just wanted to voice my support of enforcing MFA especially for the top 100-1000 gems, and encouraging it on signup. I'm not sure if we need to require it for new users but maybe making it as part of the signup step will help.

Re "single use tokens", I like that idea too - I'd love to see that as part of the RubyGems.org API!

@jchestershopify
Copy link
Contributor Author

Closing now that we've opened #36.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants