4

A recently-published article demonstrates a way to make "typo-squatting" attacks on popular programming package managers. It singles out Python's pip, Ruby's gem and Node's npm systems, and shows that they have two things in common:

  1. Packages can be submitted and accepted automatically, with no manual review or human oversight
  2. Packages can cause the package manager to execute arbitrary "setup" code on the client system at install-time.

This means that it's possible to register a package with a name that's very similar to that of a popular package, and get your package (complete with a malicious setup script) installed anytime someone mistypes the package name.

This makes me wonder, does NuGet have these same two characteristics? Does it have any mechanism in place to mitigate attacks of this type?

Mason Wheeler
  • 82,151
  • 24
  • 234
  • 309
  • 1
    https://github.com/NuGet/Home/issues/2974 – Robert Harvey Jun 14 '16 at 16:49
  • 1
    I'm not sure that I would call this an "attack", though. It's very well-known at least within the Ruby community that installing a gem requires absolute trust, and the even simpler version of this attack of simply uploading a gem with the *same* name but higher version number is well-known as well. – Jörg W Mittag Jun 14 '16 at 17:12
  • @JörgWMittag Ouch! That's really ugly. So there's no mechanism at all in the `gem` system to ensure that a person retains control of the gem package-name that they introduced? – Mason Wheeler Jun 14 '16 at 17:57
  • Nope. Although, again, that's not unique to RubyGems, pretty much every package management system I am familiar with works the same way. Of course, any particular repository host may impose their own restrictions in addition to how RubyGems works, e.g. a repository host may decide to only allow further uploads of a gem of a particular name through the same API key that uploaded the first version or something like that. But that is a restriction of the repository, not RubyGems. If I create my own local repository with my own local version of Rails with some bugfix that is missing from the … – Jörg W Mittag Jun 14 '16 at 19:31
  • … official version, I *want* my version to take precedence. I would consider it a *bug* if this wasn't possible. – Jörg W Mittag Jun 14 '16 at 19:32
  • @JörgWMittag And that's all well and good if you're hosting your own private repo, but if I say `gem install foo` against the default public Gems repository, I'd want to have some reasonable expectation that what I'm getting actually comes from the original `foo` author! I'd consider not having that available a very serious bug! – Mason Wheeler Jun 14 '16 at 19:37
  • And that's exactly what RubyGems.Org does. Only the original author is allowed to publish new versions of a Gem on RubyGems.Org. However, like I said, that's not a feature of RubyGems, that's a private internal policy decision of one particular host of one particular repository. Every repository host is free to make their own policy decisions and every RubyGems user is free to use or not use any particular repository. – Jörg W Mittag Jun 14 '16 at 20:14

1 Answers1

3

Packages can be submitted and accepted automatically, with no manual review or human oversight

Yes.

Packages can cause the package manager to execute arbitrary "setup" code on the client system at install-time.

The "old" project model allows running PowerShell scripts, so yes I would say this is also an issue for NuGet. Even the new ones are vulnerable in that as soon as they "run" their project importing the package, the assembly can just do something malicious.

Does it have any mechanism in place to mitigate attacks of this type?

I've seen a few organizations adopt the practice of banning the Microsoft NuGet repository, and set up a local server with vetted packages.

It's also worth pointing out that while Package Signing in issue #2577 appears to be coming, a writeup of it on the Nuget blog makes the distinct point that package signing will not completely address this:

This signing system is not trying to tell you that NuGet can verify that a package is the right version of Newtonsoft.Json, from James Newton-King. Instead, we can say that it’s Newtonsoft.Json from someone in control of the private key for some certificate X. Actually verifying that James Newton-King is in control of that certificate is a secondary process that we are not providing here.

Presumably then this signing will be available to anyone, and a squatter could simply just sign their package.

https://github.com/NuGet/Home/issues/2974#issuecomment-225949342

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • Re: the last paragraph: that's just how signing works in general, though. It never tells you the identity of the person, it only tells you the signing key, it's your job to verify the signer's identity, whether that be for an HTTPS connection in your browser, a signed email, or a NuGet/RubyGems package. The blog post makes it sound like that is something specific to how NuGet uses signatures. – Jörg W Mittag Jun 14 '16 at 17:16
  • @JörgWMittag Presumably if NuGet were to support EV Code Signing (yes that's a thing) then there is *better* (not guaranteed) assertion of the identity of the signer. If the package manager were to say, "Yes, this package is EV signed and here's the distinguished name of the certificate" then you have a pretty good chance that the name on the certificate is right. Whether or not you trust that name is up to you. – vcsjones Jun 14 '16 at 17:25