Logo
15 December 2024

Dependency Confusion Attacks and Prevention : Full guide

Dependency confusion attacks


Nowadays, developers rely heavily on packages (dependencies) to build products. These packages enable developers to focus on business logic instead of spending time on technical implementations. They also facilitate sharing logic between services or applications. However, these packages come with significant challenges, particularly in terms of security.

The problem of dependency confusion arises when there exists a public package with the same name as one of an organization’s private packages, causing ‘confusion’ for the package manager in use on which of the packages to fetch.

Post

Here, we can easily observe that the public registry contains a version higher name-package@2.0.0 than the one available in the private registry name-package@1.0.0

Therefore, the package manager (npm) will select the latest version of the package, which is the one available in the public registry.

How Dependency Confusion attacks work

After conducting reconnaissance, an attacker might discover the project's package.json file, which lists all its dependencies, as shown below.

Post


Here, we can easily observe that some packages, like express, are public and accessible. However, the packages highlighted in red are not available in the package manager (npm).

Post

At this point, the attacker can easily create and publish a malicious package (e.g., pplogger@0.5), ensuring the version is higher than the one specified in the project's package.json file.

Why does the attacker need to create a package with a higher version? If we examine the package.json file, it specifies pplogger:^0.2. When the npm install command is executed, the package manager will fetch the latest compatible minor or patch version starting from 0.2. This means that any newer version within the 0.0.x range would be installed, provided it adheres to the semantic versioning rules for the caret (^) operator.

All the attacker needs to do now is wait for someone to run the npm install command on their machine, causing the malicious package to be installed on the target system.

This technique enables hackers to achieve Remote Code Execution (RCE), allowing them to upload backdoors onto both developers' machines and server systems.

How to Prevent Dependency Confusion Attacks

Enable Namespace Restrictions

Adopt a standardized naming convention for all internal packages by using company-specific identifiers, such as @company-name/package-name to prevent packages from being overwritten or impersonated in public registries.

Use Private Package Repositories

Utilize a private repository registry for internal packages (eg : GitHub Private Repositories), enforce namespace restrictions, and configure your package manager to prioritize private registries for these packages.

Use Lockfiles

Utilize lockfiles (package-lock.json, yarn.lock, or equivalent) to lock dependency versions and ensure consistency across environments.