Listen to this Post
cdxgen is a CLI tool and library that generates a CycloneDX Software Bill of Materials (SBOM) for a project. Its Docker image scanning module constructs an `X-Registry-Auth` header using credentials stored in DOCKER_CONFIG/config.json. The vulnerable logic, located in lib/managers/docker.js, selects which registry credentials to use by checking if a given registry hostname is a substring of the credential’s configured registry(affected from v9.9.5). Specifically:
if (forRegistry && !serverAddress.includes(forRegistry)) {
continue;
}
This substring check is not origin-safe. For example, if credentials are stored for `private-registry.example.com` and the user scans an image from `registry.example.com` (which is a substring), the condition passes and the private credentials are attached to the pull request for the attacker-controlled registry. The vulnerable code builds the `X-Registry-Auth` header using the matched credentials and sends it to the Docker daemon API for the requested image pull.
A fully local proof‑of‑concept creates a temporary Docker config with credentials for private-registry.example.com, starts a mock Docker API endpoint, sets `DOCKER_HOST` to that endpoint, and triggers cdxgen to pull from registry.example.com. The tool then outputs a decision that confirms the substring match and shows the decoded header containing the private credentials. The vulnerable versions include the npm package `@cyclonedx/cdxgen` (reviewed version 12.3.3), as well as the Single Executable Applications (SEA) binaries and container images built from that code.
DailyCVE Form
Platform: `npm`
Version: `12.3.3`
Vulnerability : `credential forwarding/misbinding`
Severity: `High`
date: `2026-05-08`
Prediction: `2025-07-31`
What Undercode Say:
Analytics
The flaw resides in a simple substring check that was intended for configuration matching but inadvertently allows a shorter hostname to match a longer one. Attackers controlling a registry (registry.example.com) can exploit any victim who has credentials for a registry whose name contains the attacker’s registry as a substring. The fix introduces strict host‑normalisation and exact matching, preventing any substring‑based credential leakage.
Bash Commands / Code
Check if your cdxgen version is vulnerable (v9.9.5 to v12.3.3) npm list @cyclonedx/cdxgen Reproduce the issue (using the official proof of concept) node submissions/github-gsa/cdxgen-docker-registry-auth-substring-forwarding/evidence/cdxgen_docker_registry_auth_substring_probe.mjs
Exploit
1. Attacker sets up a registry at `registry.example.com`.
- Victim has Docker credentials for `private-registry.example.com` stored in
~/.docker/config.json. - Victim runs `cdxgen` to scan an image from
registry.example.com/team/app:latest.
4. cdxgen’s substring check (`private-registry.example.com.includes(registry.example.com)`) is true.
- cdxgen builds `X-Registry-Auth` with the private credentials and sends it to the attacker’s registry.
- Attacker receives or observes the private credentials in the pull request.
Protection from this CVE
- Upgrade to a fixed version (≥12.3.4 or any build that includes PR 3964).
- Avoid scanning images from untrusted registries when private registry credentials are present.
- Use registry hostnames that are not substrings of each other (e.g., avoid `private-registry-xyz.example.com` while having credentials for
registry-xyz.example.com).
Impact
- Credentials for a private registry can be forwarded to a different registry whose hostname is a substring.
- An attacker who controls the target registry can obtain those credentials, leading to unauthorised image pulls, pushes, or lateral movement into the victim’s container infrastructure.
- Affects both the npm package and any SEA binaries or container images derived from the vulnerable source.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

