Full Report
Dependabot is a Github bot that automatically updates out-of-date dependencies by making PRs. It's a super useful feature for maintaining up-to-date dependencies. In NPM packages, most of these only use a version. However, it's also possible to use a github.com link with a branch name. This is commonly used for private packages as opposed to setting up an internal NPM registry. Dependabot will attempt to update all dependencies that it knows about in the public repo to the most recent version. To the authors surprise, they did not have any special cases for github repos! So, if you registered the name of a package publicly, then dependabot would attempt to replace the private version of it. In order to do this, you would need to guess the name of a private-internal repo. Sometimes, this information can be leaked though. To fix this, dependabot removed the git dependency to NPM public registry mapping that it was trying to do. Clearly, there was an issue with this. According to the author, Bundle and NPM were both vulnerable to this. Obviously, this leads to an RCE if the dependency is added. Overall, a good bug in some important code! Although many of the dependabot PRs must be approved, it's easy to overlook this. Additionally, some repos use the auto-merge workflow for dependabot, making this easier to exploit.
Analysis Summary
# Vulnerability: Dependabot Dependency Confusion (Git-to-Registry Swap)
## CVE Details
- **CVE ID**: Not explicitly assigned in the report (GitHub historically handles many internal sub-component bugs via Bounty without formal CVEs, though it functionally represents a **Dependency Confusion** flaw).
- **CVSS Score**: High (Estimated 7.5 - 8.2 range)
- **CWE**: CWE-494: Download of Code Without Integrity Check / CWE-427: Uncontrolled Search Path Element
## Affected Systems
- **Products**: GitHub Dependabot (specifically `dependabot-core`)
- **Versions**: Versions prior to the fix implemented around May 2023.
- **Configurations**:
- Projects using private Git dependencies (e.g., `"pkg": "git+ssh://[email protected]:org/repo.git"`) in `package.json` or Bundler.
- Projects with Dependabot enabled.
- High risk for projects utilizing **auto-merge** workflows for Dependabot PRs.
## Vulnerability Description
The flaw existed in a Dependabot feature designed to facilitate the transition from a temporary Git-based dependency back to a formal registry-based package. If a project used a Git URL as a version requirement, Dependabot would check the public NPM/RubyGems registry for a package of the same name.
If a package existed publicly, Dependabot would attempt to verify if the current Git commit was an ancestor of the latest registry version. However, because the attacker controls the metadata of the public package, they could point the "repository" field in the public `package.json` to a repo they control that satisfies this history check. This tricked Dependabot into creating a Pull Request that converted a private Git dependency into a malicious public registry dependency.
## Exploitation
- **Status**: PoC available; reported via Bug Bounty.
- **Complexity**: Medium (Requires guessing/leaking names of private internal Git dependencies).
- **Attack Vector**: Network (Remote). An attacker publishes a squatting package to a public registry.
## Impact
- **Confidentiality**: High (RCE in CI/CD can exfiltrate environment variables and secrets).
- **Integrity**: High (Malicious code is injected into the application build).
- **Availability**: Medium (Potential for service disruption via malicious scripts).
## Remediation
### Patches
- **GitHub Update**: GitHub has removed the functionality that maps Git dependencies back to public registries within Dependabot. No user action is required for the cloud version of Dependabot.
### Workarounds
- **Disable Auto-Merge**: Immediately disable any workflows that automatically merge Dependabot Pull Requests without human review.
- **Manual Review**: Scrutinize PRs that change a dependency source from a Git URL to a registry-based version.
## Detection
- **Indicators of Compromise**: Review closed or open Dependabot PRs for unexpected "source conversion" where a `git+ssh` or `git+https` link was replaced by a standard version number from a public registry.
- **Detection Methods**: Audit `package.json` and lockfiles for packages that should only exist internally but are now pulling from public mirrors.
## References
- **Giraffe Security Original Post**: hxxps://giraffesecurity[.]dev/posts/dependabot-confusion-gaining-access-to-private-github-repositories/
- **Dependabot Core Repository**: hxxps://github[.]com/dependabot/dependabot-core