CVE-2026-59891 Overview
CVE-2026-59891 is a credential exposure vulnerability in sigstore-js, a set of JavaScript libraries for interacting with Sigstore services. The @sigstore/oci package uses substring matching when reading Docker registry credentials from the local Docker configuration file. An attacker who can influence the target registry hostname can cause credentials configured for one registry to be transmitted to a different, attacker-controlled registry. The issue affects versions prior to 0.7.1 and is tracked under [CWE-522: Insufficiently Protected Credentials].
Critical Impact
Registry credentials stored in the Docker config file may be sent to an unintended registry whose hostname shares a substring with a legitimately configured entry, enabling credential theft.
Affected Products
- sigstore-js @sigstore/oci package versions prior to 0.7.1
- JavaScript and TypeScript build pipelines that publish or verify OCI artifacts via sigstore-js
- CI/CD workflows that rely on getRegistryCredentials() to resolve Docker registry authentication
Discovery Timeline
- 2026-07-14 - CVE-2026-59891 published to NVD
- 2026-07-15 - Last updated in NVD database
Technical Details for CVE-2026-59891
Vulnerability Analysis
The getRegistryCredentials() function in packages/oci/src/credentials.ts reads entries from the Docker configuration file to determine which credentials to send with a registry request. Instead of comparing the target registry against configured auth keys using an exact host match, the function checks whether an auth key contains the target registry string as a substring. This substring comparison violates the least-privilege principle for credential handling and enables credential misrouting.
Because Docker Hub credentials are commonly stored under multiple aliases such as docker.io, index.docker.io, and registry-1.docker.io, developers frequently populate several auth entries. Any of these entries can be inadvertently selected for an unrelated registry whose hostname shares a substring, causing the client to attach the wrong credentials to an outbound request.
Root Cause
The root cause is improper input comparison during credential lookup. The lookup routine used a loose includes()-style substring test rather than canonicalizing both the configured key and the requested registry into a normalized host[:port] form before performing an exact match. Combined with the lack of scheme and path stripping, this allowed unrelated registries to satisfy the match condition.
Attack Vector
An attacker who controls, registers, or supplies a registry name that is a substring of a legitimate configured host can trigger the vulnerable lookup during any push, pull, or signing operation performed with sigstore-js. The client then transmits credentials intended for the legitimate registry to the attacker-controlled endpoint. Exploitation requires the victim to initiate a request to the malicious registry, consistent with the user-interaction requirement in the advisory.
HttpHeaders?: { [key: string]: string };
};
+// Well-known aliases for the Docker Hub registry. Docker stores Hub
+// credentials under a handful of different keys depending on how the user
+// authenticated, so they all need to canonicalize to the same host.
+const DOCKER_HUB_ALIASES = new Set([
+ 'docker.io',
+ 'index.docker.io',
+ 'registry-1.docker.io',
+]);
+
+// Canonicalizes a registry hostname or a Docker config auth key to a
+// comparable host[:port] value by stripping any scheme/path and normalizing
+// the well-known Docker Hub aliases.
+const canonicalizeRegistry = (value: string): string => {
+ // Strip the scheme (e.g. "https://") if present.
+ let host = value.replace(/^https?:\/\//, '');
+ // Strip any path/query (everything after the first '/').
+ host = host.split('/')[0];
+
+ return DOCKER_HUB_ALIASES.has(host) ? 'docker.io' : host;
+};
+
// Returns the credentials for a given registry by reading the Docker config
// file.
export const getRegistryCredentials = (imageName: string): Credentials => {
Source: sigstore-js commit 85c5838 — the patch introduces canonicalizeRegistry() to normalize both sides of the comparison and enforce exact host matching.
Detection Methods for CVE-2026-59891
Indicators of Compromise
- Outbound HTTPS requests from build agents to registry hostnames that were not configured in ~/.docker/config.json but partially match a configured entry.
- Authentication headers (Authorization: Basic ...) transmitted to registries that do not own the corresponding credential.
- Unexpected WWW-Authenticate challenges or 401 responses followed by credential retries against unfamiliar registries.
Detection Strategies
- Inventory all Node.js projects and CI images that depend on @sigstore/oci at versions below 0.7.1 using software composition analysis.
- Audit Docker configuration files across build hosts for auth entries whose keys are substrings of one another (for example, myregistry.io and evil-myregistry.io.attacker.tld).
- Inspect CI pipeline logs for image references that resolve to unexpected registry hostnames prior to a signing or push operation.
Monitoring Recommendations
- Log and alert on egress DNS lookups and TLS SNI values from build runners that target registries outside an approved allowlist.
- Forward CI runner process telemetry into a security data lake and correlate node process activity with outbound registry connections.
- Track dependency updates for sigstore-js packages through your SBOM and flag any regression to versions prior to 0.7.1.
How to Mitigate CVE-2026-59891
Immediate Actions Required
- Upgrade @sigstore/oci and any transitive sigstore-js dependencies to version 0.7.1 or later in every application, CI job, and container image.
- Rotate any registry credentials that could have been exposed by pipelines running vulnerable versions, particularly Docker Hub tokens and private registry passwords.
- Restrict outbound network access from build runners to an explicit allowlist of trusted registry hostnames.
Patch Information
The fix is available in the sigstore-js @sigstore/oci@0.7.1 release and applied via commit 85c5838. The patch introduces the canonicalizeRegistry() helper, strips scheme and path components, normalizes Docker Hub aliases, and requires exact host matching before returning credentials. See GHSA-pf56-329r-95rw for the full advisory.
Workarounds
- Remove ambiguous or unused entries from ~/.docker/config.json so no configured auth key is a substring of any other registry hostname referenced during builds.
- Use short-lived, per-registry credentials issued by a secrets manager rather than long-lived tokens stored in the Docker config file.
- Enforce network egress policies that block build agents from reaching registries outside a curated allowlist until the upgrade is deployed.
# Update sigstore-js OCI package to the fixed version
npm install @sigstore/oci@^0.7.1
# Verify the installed version resolves at or above 0.7.1
npm ls @sigstore/oci
# Audit the Docker config for overlapping registry keys
jq '.auths | keys' ~/.docker/config.json
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

