What Is a Dependency Confusion Attack?
A dependency confusion attack exploits the way software dependencies are managed and resolved by automatic package managers. It occurs when attackers deploy malicious packages with the same name as legitimate packages on public repositories. The fake packages can then be mistakenly pulled into projects, posing serious security risks.
This type of attack leverages the mixed use of private package feeds and public repositories. When a dependency is requested, if the public version has a higher version number than the private, the package manager might opt for the malicious, public version, unknowingly integrating compromised code into the application. In other cases, developers might accidentally include the malicious package in a project because of the similar name, without recognizing it comes from a public repo.
This is part of a series of articles about application security
The Impact of Dependency Confusion Attacks
Dependency confusion attacks can have significant and far-reaching impacts on organizations, potentially compromising security, operational integrity, and business continuity:
- Data breaches and information leakage: The most immediate and concerning impact is the potential for data breaches. Malicious packages may include code designed to exfiltrate sensitive data, such as user credentials, personally identifiable information (PII), or proprietary business information.
- System compromise and network intrusion: Dependency confusion attacks can serve as an entry point for attackers to explore and exploit other vulnerabilities within an organization’s network. Once the malicious code is executed, it can act as a backdoor, allowing attackers sustained access to corporate networks and the ability to deploy further malicious payloads.
- Operational disruption: If critical systems rely on compromised packages, attackers could potentially disable functionalities or manipulate operations, leading to operational disruptions and downtime.
- Compromise of software supply chain: These attacks highlight vulnerabilities in the software supply chain, affecting not just a single application but potentially any software that shares the compromised dependency.
How Does a Dependency Confusion Attack Work?
The attack starts when an attacker identifies internal package names used by a target company. These names can be inferred from public code repositories, error logs, or other exposed internal data. The attacker then creates a package with the same or similar name and uploads it to a public package repository, setting a high version number to ensure its selection over internal packages.
The next time the target company’s software builds occur, the package manager may automatically pull this malicious package instead of the intended internal package. The company’s systems then execute the malicious code, compromising security without immediate detection.
Example of a Dependency Confusion Attack
Consider a practical scenario in which a Python developer is enhancing their project with the popular “asyncio” library to facilitate HTTP requests. The developer includes a simple line of code in their application to import this library:
import asyncio
In this scenario, the developer’s project settings are configured to automatically fetch the latest version of dependencies. The developer is unaware that an attacker has created a malicious version of the “asyncio” library and uploaded it to the Python Package Index (PyPI) with a version number that is higher than the current legitimate version.
Due to the higher version number, when the developer runs their project, the package manager, like pip, prioritizes this new malicious version from PyPI over the older but legitimate one. The package manager automatically downloads and integrates the malicious “asyncio” package into the developer’s project.
This results in the developer unknowingly executing harmful code embedded within the dependency. The malicious package could contain functionalities designed to steal sensitive data or execute unauthorized remote commands.
Mitigating the attack
To prevent this attack, the developer could specify the version of the package:
import asyncio==3.4.3
By specifying the version, the developer ensures that the package manager fetches exactly version 3.4.3, thereby avoiding any newer, potentially malicious versions uploaded to public repositories.
The developer could also modify the project to fetch dependencies from a controlled, private repository rather than public ones. This can be achieved by adjusting the package installation command to specify a private index URL, as shown below:
pip install --index-url https://internalrepo.com/pypi/ asyncio==3.4.3
5 Ways to Prevent Dependency Confusion Attacks
There are several organizations that organizations can take to reduce the risk of dependency confusion attacks.
1. Utilize Scoped or Namespaced Packages
Scopes allow organizations to group related packages under a unique namespace, reducing the risk of naming collisions with public packages. This method makes it significantly harder for attackers to mimic internal package names successfully.
Most modern package managers support scope-based resolution, which prioritizes scoped packages over others. This setting ensures that during dependency resolution, the integrity of the package supply chain is maintained, shielding internal projects from external malicious attacks.
2. Secure the Build Environment
Securing the build environment involves strict control over how and from where dependencies are fetched. Enforcing rules to ensure that only trusted sources are used for package downloads can prevent the inadvertent inclusion of malicious code. This process includes configuring package managers to reject unverified repositories.
Additionally, organizations should continuously monitor and audit the build environments to detect and respond to any unauthorized changes or network requests.
3. Validate Hashes or Checksums
Hashes or checksums of packages should be validated before they are integrated into the build process. By ensuring that the downloaded package’s checksum matches the known good checksum, organizations can ascertain the authenticity and integrity of the package.
This method protects against compromised packages slipping through because even if a malicious package replicates the name and version, it cannot replicate the exact hash without being noticeably different from the original.
4. Use Private Package Registries
Configuring and using private package registries adds a layer of security by limiting the pool of accessible packages to those vetted and approved by the organization. These registries can enforce strict authentication and authorization before allowing access to download or upload packages, further mitigating the risk of external attacks.
However it should be noted that this measure in itself does not prevent dependency confusion, because attackers can create a package with a similar name on a public repository and trick developers or automated systems into using it.
5. Regularly Update Dependencies
Regular updates of dependencies ensure that the latest security patches and fixes are incorporated, reducing vulnerabilities that attackers might exploit, including those related to dependency confusion. Setting up automated tools to manage and update dependencies routinely can help in maintaining up-to-date and secure software stacks.
Frequent audits of the dependency list to identify deprecated or unsafe packages can prevent security gaps that might be exploited in a dependency confusion attack.
Dependency Confusion Prevention with Imperva
Imperva can defend against attacks like dependency confusion with its Runtime Application Self-Protection (RASP), a real-time attack detection and prevention from your application runtime environment goes wherever your applications go. Stop external attacks and injections and reduce your vulnerability backlog.
Beyond Dependency Confusion, Imperva provides comprehensive protection for applications, APIs, and microservices:
Web Application Firewall – Prevent attacks with world-class analysis of web traffic to your applications.
Runtime Application Self-Protection (RASP) – Real-time attack detection and prevention from your application runtime environment goes wherever your applications go. Stop external attacks and injections and reduce your vulnerability backlog.
API Security – Automated API protection ensures your API endpoints are protected as they are published, shielding your applications from exploitation.
Advanced Bot Protection – Prevent business logic attacks from all access points – websites, mobile apps and APIs. Gain seamless visibility and control over bot traffic to stop online fraud through account takeover or competitive price scraping.
DDoS Protection – Block attack traffic at the edge to ensure business continuity with guaranteed uptime and no performance impact. Secure your on premises or cloud-based assets – whether you’re hosted in AWS, Microsoft Azure, or Google Public Cloud.
Attack Analytics – Ensures complete visibility with machine learning and domain expertise across the application security stack to reveal patterns in the noise and detect application attacks, enabling you to isolate and prevent attack campaigns.
Client-Side Protection – Gain visibility and control over third-party JavaScript code to reduce the risk of supply chain fraud, prevent data breaches, and client-side attacks.