
Isolated regression and security-control lab for CVE-2026-59891 in @sigstore/oci
An isolated hands-on lab and read-only audit project that compares the actual vulnerable and fixed versions of @sigstore/oci with the same input and checks environment-specific exposure conditions.
The CVE Reporter for this project is gyubin02.
Recruitment/interview summary: CVE-2026-59891 vulnerability management automation case
The core of CVE-2026-59891 is hostname confusion that occurs when selecting Registry credentials.
0.7.0: Because cr.io is contained within the ghcr.io string, it may select ghcr.io credentials.0.7.1: After normalizing the hostname, it selects only exactly matching credentials.This repository first automatically verifies two credential selection scenarios.
ghcr.io credentials exist, but the target is cr.iocr.io credential that exactly matches the targetThe vulnerable version must incorrectly select credentials in the first scenario, and the fixed version must reject them. Both versions must succeed in the second, normal scenario.
We also added a dynamic comparison that uses a one-off mock Registry at 127.0.0.1 instead of a real external Registry. The vulnerable version 0.7.0 makes 2 local requests, and after the authentication challenge a synthetic Authorization header is observed on the second request. The fixed version 0.7.1 is rejected at the credential selection stage, resulting in 0 requests. Only the observation flag and request count remain in the results, instead of header values.
cve-2026-59891-audit reads only the metadata of the target project's package-lock.json and an explicitly specified Docker config to distinguish the following:
@sigstore/oci installation locations and versionsRun directly with the synthetic fixture:
npm run audit:demo
Audit another Node.js project:
npm run audit:project -- \
--project ../target-project \
--docker-config ../review-copy/config.json \
--image cr.io/example/demo \
--destination-trust unknown \
--format markdown \
--output reports/cve-2026-59891.md
--destination-trust must explicitly specify one of the following:
trusted: Confirmed that destination is restricted by code and an allowlistuntrusted: External input or workflow input affects destinationunknown: Not yet confirmedVerdicts are divided into exposure_conditions_met, potential_exposure, affected_component_only, not_detected, and indeterminate. not_detected is only a result within the recorded input scope, not a statement of "safe" or "compliance".
~/.docker/config.json.HOME and worthless lab-user / LAB_ONLY_FAKE_TOKEN.HOME, the lab marker, and the fake values are all correct.fetch calls as tripwires.127.0.0.1 port are allowed. External and different-port HTTP, DNS resolver, TLS, UDP, global fetch, and WebSocket are blocked.--docker-config and does not infer files from HOME or DOCKER_CONFIG.Because it intentionally installs a vulnerable package, npm package publishing is blocked with "private": true. Do not use it as a dependency of production code.
For this reason, npm audit reporting 0.7.0 is an expected result, and the scope and reason for the exception are documented in SECURITY.md.
Requirements: Node.js 22.22.2+, 24.15.0+, or 26 or higher. The recommended version is pinned in .nvmrc.
npm ci --ignore-scripts
npm test
npm run demo
npm run dynamic:demo
npm run audit:fixture
npm run audit:demo
npm run evidence
Expected key output of npm run demo:
0.7.0 collision credential-selected
0.7.1 collision credential-rejected
0.7.0 exact credential-selected
0.7.1 exact credential-selected
Regression result: PASS
Expected key output of npm run dynamic:demo:
{
"vulnerable": {
"packageVersion": "0.7.0",
"credentialSelection": "credential-selected",
"requestCount": 2,
"authorizationObserved": true,
"digestVerified": true,
"networkPolicy": "exact-loopback-only"
},
"fixed": {
"packageVersion": "0.7.1",
"credentialSelection": "credential-rejected",
"requestCount": 0,
"authorizationObserved": false,
"digestVerified": false,
"networkPolicy": "exact-loopback-only"
},
"regressionResult": "PASS"
}
There are 34 automated tests in total. npm run evidence generates a total of 7 files: 6 audited artifacts plus SHA256SUMS to verify their integrity.
This project is a limited educational controlled assessment. The loopback results only demonstrate behavioral differences in a synthetic environment; they do not prove credential exposure or compromise, or control effectiveness, in real enterprise environments. It does not imply CISA certification, ISMS-P certification, or compliance with any specific organization. The Node API guard is a defense layer for observed execution paths of locked dependencies, not an OS-level network namespace or firewall.
Detailed scope, tests, risk, and control documentation is in docs/, and npm run evidence generates reproducible execution evidence and a SHA-256 manifest.
npm-shrinkwrap.json is found, it fails instead of asserting safety.