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

Preventing the "Dependency Confusion" attack #10566

Closed
waf opened this issue Feb 11, 2021 · 17 comments
Closed

Preventing the "Dependency Confusion" attack #10566

waf opened this issue Feb 11, 2021 · 17 comments
Assignees

Comments

@waf
Copy link

waf commented Feb 11, 2021

Details about Problem

A security researcher has publicized a "Dependency Confusion" problem1 that affects most package managers, and I suspect nuget is affected as well.

For example, say my company has an internal nuget package, named mycompany-logger, hosted on an internal nuget server. If someone uploads a malicious package with the same name to nuget.org, with either an equal or slightly higher version, would a package restore pull down this malicious package instead?

Research Done

Initially, I thought that using a NuGet.config with the company internal packageSource listed first would stop this, but I see the following documentation:

The order is ignored during restore operations and with any project using the PackageReference format.

One way of solving this might be adding the ability to pin a nuget package to a particular packageSource, so e.g. mycompany-logger would only ever be downloaded from the internal nuget server. Are there any ways to mitigate this today? Thanks.

1 This is a Medium article, if the link is blocked see this alternate source.

@hypervtechnics
Copy link

For reference: #5611

@hrumhurum
Copy link

hrumhurum commented Feb 11, 2021

This is a serious issue. Companies tend to use private feeds, so it is a no brainer to undercut all of them by publishing a poisoned package at nuget.org.

What makes matters worse is that in case of .NET the private package names are trivially deductible: just use the file names of assemblies; most of them will be immediate and perfect hits. The same goes to versions: assemblies tend to directly reflect package versions 1:1.

The funny thing is [email protected] designated for ID prefix registrations is totally unresponsive.

EDIT: good folks at nuget.org responded and provided ID prefix reservation for our company.

@JonDouglas
Copy link
Contributor

JonDouglas commented Feb 16, 2021

Hi everyone,

We are working on providing a proposal with a solution to allow you to pin packages to a specific source. Please keep an eye on https://github.com/NuGet/Home/tree/dev/proposed for a concept called Source Pinning or Package Namespaces. It's almost ready to be shared with you all.

We also have a secure supply chain best practices documentation. Please provide us your feedback on it using the "Feedback" button at the top right.

https://docs.microsoft.com/nuget/concepts/security-best-practices

Additionally, see this whitepaper regarding best practices when using private package feeds.

@ghost
Copy link

ghost commented Mar 7, 2021

Hi everyone,

We are working on providing a proposal with a solution to allow you to pin packages to a specific source. Please keep an eye on https://github.com/NuGet/Home/tree/dev/proposed for a concept called Source Pinning. It's almost ready to be shared with you all.

We also have a secure supply chain best practices documentation. Please provide us your feedback on it using the "Feedback" button at the top right.

https://docs.microsoft.com/nuget/concepts/security-best-practices

Additionally, see this whitepaper regarding best practices when using private package feeds.

No one of them is really good solution.

The best way is simply to implement this one: #5611

Priority will solve the problem.

@JonDouglas
Copy link
Contributor

For those on this thread, we have now published a proposal for a feature we believe will help secure your software supply chain even further. Please feel free to provide your feedback directly on the PR.

#10660

@omkarkhair
Copy link

In order to prevent dependency confusion for projects that rely on Nuget.org and a Private feed, is it also a solution to list only the private feed into nuget.config and configure the private feed to use Nuget.org as an upstream source?
https://docs.microsoft.com/en-us/azure/devops/artifacts/nuget/upstream-sources?view=azure-devops

So if Nuget.org has a package with the same name as one published in the private feed, the private feed will take precedence. Is my assumption correct?

@JVimes
Copy link

JVimes commented Jan 13, 2022

...is it also a solution to list only the private feed into nuget.config and configure the private feed to use Nuget.org as an upstream source?

I think so, maybe as a stopgap. I don't think it's practical in the long term. It's hard to make sure that config is done for every dev environment now and in the future.

@JVimes
Copy link

JVimes commented Jan 13, 2022

Correct me if I'm wrong, but it looks like #10660 does not fix the vulnerability in NuGet. It has each user mitigate it on each of their environments.

To fix the vulnerability, the NuGet clients must detect duplicate packages and stop with a helpful message. Then the user can mitigate how they see fit (nuget.org takedown, #10660, order sources, etc.)

This does away with the recent "fastest response wins" behavior. Everything worked before that behavior, and it removed one way to mitigate the vulnerability (ordered sources) and made builds less deterministic. Seems like a win-win.

@Basssiiie
Copy link

Basssiiie commented Jan 13, 2022

It's hard to make sure that config is done for every dev environment now and in the future.

You can make solution scoped nuget.configs that can be checked in into source control by putting the nuget.config in the same folder as the solution file. No need to configure it per dev environment if everyone works on the same solution.

To fix the vulnerability, the NuGet clients must detect duplicate packages and stop with a helpful message.

One potential issue with an error on duplicate packages is that it requires all sources to respond. If one source is down, then should it happily take the other source or fail for all packages because it cannot verify for any package whether there's a duplicate?

@JVimes
Copy link

JVimes commented Jan 13, 2022

You can make solution scoped nuget.configs that can be checked in into source contro

Same problem: have to remember to do it for every project now and in the future.

potential issue with an error on duplicate packages is that it requires all sources to respond. If one source is down

What are you using duplicate sources for? I've never seen anyone use that feature on purpose.

@Basssiiie
Copy link

Basssiiie commented Jan 13, 2022

What are you using duplicate sources for? I've never seen anyone use that feature on purpose.

What if you have your private source and the official Nuget source in your nuget.config. You have package A in private source. Now a bad person uploads a package A to Nuget. Your idea was to then fail the restore and show a message. That's fine and all, but what if bad person somehow takes down (connection to) your private source as well, then the restore will succeed because package A was still found at the Nuget source. To prevent that you'd need to successfully verify at both sources that the package only lives at one of them. That's the idea I was trying to explain. It seems like a less stable idea than the source pinning that has been proposed.

@JonDouglas
Copy link
Contributor

Hi everyone,

We have a feature that we released last year that should help with this problem.

https://devblogs.microsoft.com/nuget/introducing-package-source-mapping/

https://docs.microsoft.com/nuget/consume-packages/package-source-mapping

While I know you're discussing this problem further, this issue should be closed for now. Please feel free to open up another issue regarding specific problems & ideas to improve preventing dependency confusion with the options today i.e. source mapping, lock files, etc.

One ideal practice would be to map one source per package to provide you with the true determinism you seek. In the future, we may be able to add features like Package Validation to help validate at the version & binary level.

@JVimes
Copy link

JVimes commented Jan 14, 2022

@JonDouglas That does not fix the vulnerability in the NuGet clients. It was wrong to close this issue.

@JonDouglas
Copy link
Contributor

@JVimes We would love to understand your situation further as this feature can always be improved. A new issue would be very appreciated and helpful.

Because we have shipped a solution in the context of this issue, we will close the issue for now. If others feel that this isn't fully addressed, we can always reopen this issue.

@richard-fine
Copy link

richard-fine commented Jun 5, 2023

Hey,

Package Source Mapping solves this problem for packages inside a solution. However, there is another another important use case which it does not address: dotnet tool install.

For example, I am looking at creating and distributing a tool at my company which would bootstrap the user's development environment, so the onboarding experience for a new developer at the company would just be: install dotnet, then dotnet tool install -g MyCompany.DevTool --add-source https://nuget.vpn.mycompany.com/, then run the tool to begin setting up their workspace. At the time that they install the tool, they may not have a workspace or solution present. (Heck, they may not even have Git installed at that point...)

Because dotnet tool install takes the custom package source in addition to the global ones, instead of allowing me to override them completely, it is still subject to dependency confusion attacks.

@baronfel
Copy link

baronfel commented Jun 5, 2023

@richard-fine this is an important point to raise - we're currently reworking the tool install experience to not use an implicit restore and instead use the NuGet APIs directly. I'll make sure that as a design point we take PSM instructions from the NuGet.config into account here.

@xoofx
Copy link

xoofx commented Jun 5, 2023

@richard-fine this is an important point to raise - we're currently reworking the tool install experience to not use an implicit restore and instead use the NuGet APIs directly. I'll make sure that as a design point we take PSM instructions from the NuGet.config into account here.

The usage of nuget.config would be much welcome, but as @richard-fine was suggesting, a e.g --set-source instead of --add-source would be welcome as well to make sure that only the source specified from the command line is going to be used and none from a NuGet.config or default config.

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

No branches or pull requests