GHSA-PF56-329R-95RW

Vulnerability from github – Published: 2026-07-21 19:34 – Updated: 2026-07-21 19:34
VLAI
Summary
Credential confusion in @sigstore/oci can leak registry credentials to an attacker-controlled registry
Details

Impact

This is a credential-exposure / credential-confusion issue.

getRegistryCredentials() reads credentials from the Docker config file (~/.docker/config.json) and selects an entry by checking whether any configured auth key contains the target registry string:

Object.keys(dockerConfig.auths || {}).find((key) => key.includes(registry))

Because this is a substring match rather than an exact host match, credentials configured for one registry can be selected for — and transmitted to — a different registry whose hostname has a substring relationship with a configured auth key (for example, an attacker-controlled cr.io matches a configured ghcr.io).

Who is impacted: Any consumer of @sigstore/oci that uploads artifacts to an OCI registry using credentials from a Docker config, where the destination registry/image reference can be influenced by an untrusted party. This includes @actions/attest and the actions/attest, actions/attest-build-provenance, and actions/attest-sbom GitHub Actions when run with push-to-registry: true, where the subject-name input determines the destination registry.

This is classified as a critical vulnerability given the potential, in a theoretical worst-case scenario, to expose long-lived registry credentials. However, in practice, exploitation requires all of the following:

  • The Docker config on the host contains credentials for a registry.
  • The destination registry/image reference is influenced by an untrusted source.
  • The attacker controls a registry whose hostname is a substring of (or is otherwise contained within) a configured Docker auth key.

Under those conditions, registry credentials present on the host (e.g. a GHCR, Docker Hub, or cloud-registry token) can be sent to an attacker-controlled registry during the authentication exchange.

Patches

Fixed in @sigstore/oci@0.7.1. Credential selection now requires an exact host match: both the target registry and each Docker auth key are canonicalized — stripping any https?:// scheme and path and normalizing the Docker Hub aliases (index.docker.io / registry-1.docker.io / docker.io) — and compared for equality. When no exact match exists, credential lookup now fails rather than falling back to an unrelated credential.

  • Affected versions: <= 0.7.0 (all releases from 0.1.0).
  • Patched version: 0.7.1.

Downstream consumers should pick up the patched @sigstore/oci; subsequent releases of @actions/attest and the actions/attest* GitHub Actions will bundle the fix.

Workarounds

  • Treat the destination registry/image reference as trusted input — do not allow untrusted sources to influence the registry/image reference passed to @sigstore/oci (or the subject-name of actions/attest* when push-to-registry: true).
  • Limit the credentials available in the host's Docker config to only those required for the operation, and avoid authenticating to registries whose hostnames have substring relationships with potential untrusted destinations.
  • Scope registry tokens narrowly and prefer short-lived credentials.
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@sigstore/oci"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.7.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-59891"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-522"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-21T19:34:05Z",
    "nvd_published_at": "2026-07-14T17:17:15Z",
    "severity": "CRITICAL"
  },
  "details": "### Impact\n\nThis is a credential-exposure / credential-confusion issue.\n\n`getRegistryCredentials()` reads credentials from the Docker config file (`~/.docker/config.json`) and selects an entry by checking whether any configured auth key **contains** the target registry string:\n\n```js\nObject.keys(dockerConfig.auths || {}).find((key) =\u003e key.includes(registry))\n```\n\nBecause this is a **substring match rather than an exact host match**, credentials configured for one registry can be selected for \u2014 and transmitted to \u2014 a *different* registry whose hostname has a substring relationship with a configured auth key (for example, an attacker-controlled `cr.io` matches a configured `ghcr.io`).\n\n**Who is impacted:** Any consumer of `@sigstore/oci` that uploads artifacts to an OCI registry using credentials from a Docker config, where the destination registry/image reference can be influenced by an untrusted party. This includes `@actions/attest` and the `actions/attest`, `actions/attest-build-provenance`, and `actions/attest-sbom` GitHub Actions when run with `push-to-registry: true`, where the `subject-name` input determines the destination registry.\n\nThis is classified as a **critical** vulnerability given the potential, in a theoretical worst-case scenario, to expose long-lived registry credentials. However, in practice, exploitation requires all of the following:\n\n- The Docker config on the host contains credentials for a registry.\n- The destination registry/image reference is influenced by an untrusted source.\n- The attacker controls a registry whose hostname is a substring of (or is otherwise contained within) a configured Docker auth key.\n\nUnder those conditions, registry credentials present on the host (e.g. a GHCR, Docker Hub, or cloud-registry token) can be sent to an attacker-controlled registry during the authentication exchange.\n\n### Patches\n\nFixed in **`@sigstore/oci@0.7.1`**. Credential selection now requires an **exact host match**: both the target registry and each Docker auth key are canonicalized \u2014 stripping any `https?://` scheme and path and normalizing the Docker Hub aliases (`index.docker.io` / `registry-1.docker.io` / `docker.io`) \u2014 and compared for equality. When no exact match exists, credential lookup now fails rather than falling back to an unrelated credential.\n\n- **Affected versions:** `\u003c= 0.7.0` (all releases from `0.1.0`).\n- **Patched version:** `0.7.1`.\n\nDownstream consumers should pick up the patched `@sigstore/oci`; subsequent releases of `@actions/attest` and the `actions/attest*` GitHub Actions will bundle the fix.\n\n### Workarounds\n\n- Treat the destination registry/image reference as trusted input \u2014 do not allow untrusted sources to influence the registry/image reference passed to `@sigstore/oci` (or the `subject-name` of `actions/attest*` when `push-to-registry: true`).\n- Limit the credentials available in the host\u0027s Docker config to only those required for the operation, and avoid authenticating to registries whose hostnames have substring relationships with potential untrusted destinations.\n- Scope registry tokens narrowly and prefer short-lived credentials.",
  "id": "GHSA-pf56-329r-95rw",
  "modified": "2026-07-21T19:34:05Z",
  "published": "2026-07-21T19:34:05Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/sigstore/sigstore-js/security/advisories/GHSA-pf56-329r-95rw"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-59891"
    },
    {
      "type": "WEB",
      "url": "https://github.com/sigstore/sigstore-js/commit/85c58380758b97ce1b74ef470e55cc21f9d3aa89"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/sigstore/sigstore-js"
    },
    {
      "type": "WEB",
      "url": "https://github.com/sigstore/sigstore-js/releases/tag/%40sigstore%2Foci%400.7.1"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Credential confusion in @sigstore/oci can leak registry credentials to an attacker-controlled registry"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Loading…