Investigate if package managers are vulnerable to Dependency Confusion attacks
Following this blog post detailing Dependency Confusion attacks and this issue, we had a discussion with @10io and wanted to check if packages registry are affected.
Client-side
We have little influence on how a developer will setup is environment. Depending on which source he uses, a package manager may use GitLab or the official resource.
This is a risk that we have not identified until now, and we should inform users on that. TODO: update the documentation.
NPM
Forward request to NPM
If a package is not found on GitLab, it's then forwarded to NPM, but it's not checking first on npmjs.org which means we are ok.
Scoped packages
We force user to have their package name in the format of @scope/package-name
where scope is the root namespace of the gitlab project and it must match exactly (including the case).
What can happen is that someone could create a public group using a well known package name as the group name and publishing a malicious package to GitLab. Every users that have gitlab as their default registry would get this malicious package instead of the legitimate one hosted on npmjs.org. Thanks @10io for the analysis - copy below:
Funnily enough, I wondered what would happen if someone created a babel
Group and pushed a public @babel/core
package to GitLab?
(Same situation as in the supply chain attack but corrupting a public package on GitLab) = users using the instance level API will fetch this @babel/core
package first.
This is could have higher chances to happen if users replaces the default registry with GitLab ($ npm config set registry https://gitlab.com/api/v4/packages/npm/
= all the npm
commands go through GitLab.
Post and Pre scripts
This is probably one of the most dangerous feature allowed by npm: a malicious package can have something that is automatically run without even the package being installed!
@ngeorge1 and @dappelt I don't know if we are scanning for that, but I believe monitoring packages that starts including scripts may be a way to prevent malicious changes?
NuGet
Overriding a package
When you publish a package with the same name or version as an existing package, the existing package is overwritten
, I don't think we are controlling that, but a new developper that has access to the project and overriding the package with a new one may be something that can raise a flag. It's not really an issue, just something I'm thinking in order to give more control and monitoring.
Publishing a package
If you publish the same package with the same version multiple times, each consecutive upload is saved as a separate file. When installing a package, GitLab serves the most recent file.
That behaviour can make a malicious developer to push a change that may go unnoticied since it has the same version as an existing one. And since GitLab will use the most recent file, it's almost certain it gets used at some point.
clear
According to MS doc, when <clear /> is present for a given node, NuGet ignores previously defined configuration values for that node.
Composer
We do not support forwarding requests to packagists.org
Publishing packages with the same name or version
The same package with different data, it overwrites the existing package.
same comment as for NuGet above.
Notify-batch
This is a feature that calls an URL each time a user installs a package. I'm curious to see if we can include some other commands on it rather than just an URL. Again this is something that could trigger a flag on our side.
Scripts
There are multiple possible ways to call a script: pre-install, pre-update, and even worse any command-line executable command
. As for NPM, I believe monitoring packages that starts including scripts may be a way to prevent malicious changes?
Conan
We do not support forwarding requests.
Package name
Similar to what is possible to do it NPM, we can probably also use a public group to add our package and have it used instead of the real one if the user as configure GitLab as is remote.
Go Proxy
We do not support forwarding requests. However an user can reproduce that behaviour, see below.
Defining proxies
With go env -w GOPROXY='https://gitlab.example.com/api/v4/projects/1234/packages/go,https://proxy.golang.org,direct'
Go will:
- Go attempts to fetch from the project-specific Go proxy.
- Go attempts to fetch from proxy.golang.org.
Which means the order depends on how the user defines the GOPROXY
variable.
Disabling checksum database queries
Go will instance dependencies valides the sources against sun.golang.org
and if the checksum of the fetched sources doesn’t match the checksum from the database, Go doesn’t build the dependency which will make private modules fail to build.
I don't think there's much we can do against that, but it's worth mentionning it and we probably want to update our documentation to add a note on that and multiple proxy definitions.
Maven
It can be provided with a scriptSourceDirectory
that references the scripts required to build
Packages name on group level endpoint
The group-level endpoint works with any package names. GitLab does not guarantee the uniqueness of package names within the group. You can have two projects with the same package name and package version, GitLab serves whichever one is more recent.
Otherwise a package with the same name and version as an existing one will override the existing one.
There's an option to not allow duplicate packages
PyPi
We do not allow forwarding requests to the package indexer.
GitLab also do not allow publishing a package that has the same name and version of an existing one.
Appart from NPM for which there's a setting to automatically forward requests to npmjs.org, we are not by default exposed to dependency confusion attacks.
Solutions
WIP.