Bzlmod registries and mirror_urls silently inherit `.netrc` "default" machine credentials, causing credential exfiltration risk and breaking BCR builds
- Dominant language
- Java
- Stars
- 25.8k
- Forks
- 4.6k
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 72
Description
### Description of the bug:
### **Background & P0 Regression Context**
This issue highlights a severe security regression and behavioral design flaw that mirrors **Issue #9327 (classified as a P0 in August 2019)**. The original P0 bug leaked specific `.netrc` host credentials across unconfigured HTTP redirects. While that path was fixed by evaluating headers per-hop, commit `86451bb2cf` (September 2022) introduced an even wider, global credential leak by blindly wiring `.netrc` `default` machine fallback support into automated `bzlmod` package management lookups without any validation or scoping boundaries.
### **The Problem**
When a developer or a corporate CI/CD pipeline environment configures a `default` entry in their `~/.netrc` (a standard Unix feature used for internal catch-all authentications), Bazel implicitly attaches these sensitive enterprise credentials to **every single outbound metadata request** for hosts not explicitly listed.
This creates two critical failures one a massive security risk, and the other a functional denial of service:
1. **Silent Credential Exfiltration (Supply Chain Attack Surface):**
During dependency resolution, Bazel automatically fetches metadata from registries (via `--registry`) and parses `mirror_urls` provided in a package's `source.json`. Because these endpoints can be untrusted third parties or open-source community-contributed URLs (such as the 44+ live modules in the Bazel Central Registry that currently utilize unvalidated `mirror_urls`), **user enterprise tokens (like GitHub PATs or Artifactory secrets) are silently leaked in plain text via the `Authorization` header to unknown remote hosts without any user warning.**
2. **Functional Brokenness / Denial of Service (DoS):**
Any user with a `default` entry in their `.netrc` **cannot build against the official Bazel Central Registry (BCR) at all.** The BCR correctly returns a `401 Unauthorized` whenever it receives unexpected global authentication headers, entirely blocking standard compilation workflows.
#### **Actual Text (Error Output):**
```text
ERROR: Error computing the main repository mapping: Error accessing registry [https://bcr.bazel.build](https://bcr.bazel.build): Failed to fetch registry file
[https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel](https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel):
GET returned 401 Unauthorized
### Which category does this issue belong to?
Server-Side Rules
### What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
_No response_
### Which operating system are you running Bazel on?
arch
### What is the output of `bazel info release`?
latest one
### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.
_No response_
### What's the output of `git remote get-url origin; git rev-parse HEAD` ?
```text
```
### If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.
### **Bisection Results (`bazelisk --bisect`)**
This issue is a confirmed regression. The `default` netrc credential parsing fallback logic and its implicit integration into Bzlmod fetching were introduced in the following commit range:
- **Good Version:** Bazel 5.2.0 (Bzlmod registry fetches did not blindly exfiltrate default credentials)
- **Bad Version:** Bazel 5.3.0+ (Confirmed through current HEAD / Bazel 9.1.0)
#### **Identified Regressing Commit:**
Bisection points directly to the introduction of Bzlmod's netrc fallback handling:
- **Commit Hash:** `86451bb2cf`
- **Author/Date:** September 2022
- **Impact:** This commit intentionally wired `.netrc` `default` machine fallback support into `http_{...}` rules and `DownloadManager.java` for Bzlmod registry lookups, without establishing origin/domain validation boundaries or implementing an explicit user opt-in flag.
### Have you found anything relevant by searching the web?
_No response_
### Any other information, logs, or outputs that you want to share?
[f1_registry_leak.log](https://github.com/user-attachments/files/27982351/f1_registry_leak.log)
[f3_dos_output.txt](https://github.com/user-attachments/files/27982405/f3_dos_output.txt)
Contributor guide
Research direction
Start by reading commit 86451bb2cf and the DownloadManager.java changes described in the issue, then trace how Bzlmod registry and mirror_urls requests load .netrc credentials. Reproduce with a default .netrc entry against the BCR and the supplied logs. Done means unconfigured registry and mirror hosts do not receive default credentials and BCR resolution no longer returns the reported 401.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- build-system, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100