Every CVE Search/ Get API key

CVE-2026-118763

@sigstore/oci sends the registry Authorization header to a cross-host blob-upload Location

7.4 HighFix available

sigstore-js provides JavaScript libraries for interacting with Sigstore services. Prior to 0.7.2, packages/oci/src/registry.ts contains a RegistryClient.signIn() method that stores registry Authorization and Docker configuration headers as defaults on a shared HTTP client, while RegistryClient.uploadBlob() sends a fresh PUT to an absolute blob-upload Location supplied by the registry without checking that its origin or scheme matches the registry. A malicious or compromised registry can therefore direct a user pushing an artifact through attachArtifactToImage() to an attacker-controlled host and receive the registry bearer token, Basic credentials, or custom authentication headers. Redirect-time header stripping does not prevent the leak because the cross-host PUT is a new explicit request rather than a followed redirect. This is a residual of CVE-2026-59891, whose fix changed credential selection in credentials.ts but did not constrain where credentials are sent from registry.ts. Version 0.7.2 fixes the issue by separating registry credentials from client-wide defaults and sending them only to the registry origin.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
Required

What an attacker can affect

Confidentiality
High
Integrity
None
Availability
None

Exploit likelihood

0.30%Unchanged since Oct 30, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.4

@sigstore/oci sends the registry Authorization header to a cross-host blob-upload Location

sigstore-js provides JavaScript libraries for interacting with Sigstore services. Prior to 0.7.2, packages/oci/src/registry.ts contains a RegistryClient.signIn() method that stores registry Authorization and Docker configuration headers as defaults on a shared HTTP client, while RegistryClient.uploadBlob() sends a fresh PUT to an absolute blob-upload Location supplied by the registry without checking that its origin or scheme matches the registry. A malicious or compromised registry can therefore direct a user pushing an artifact through attachArtifactToImage() to an attacker-controlled host and receive the registry bearer token, Basic credentials, or custom authentication headers. Redirect-time header stripping does not prevent the leak because the cross-host PUT is a new explicit request rather than a followed redirect. This is a residual of CVE-2026-59891, whose fix changed credential selection in credentials.ts but did not constrain where credentials are sent from registry.ts. Version 0.7.2 fixes the issue by separating registry credentials from client-wide defaults and sending them only to the registry origin.

Record
CVE-2026-118763
CVSS 3.1
7.4 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N
Weakness
CWE-522
Updated
2026-11-02
EUVDEUVD-2026-113272 7.4

sigstore-js provides JavaScript libraries for interacting with Sigstore services. Prior to 0.7.2, packages/oci/src/registry.ts contains a RegistryClient.signIn() method that stores registry Authorization and Docker configuration headers as defaults on a shared HTTP client, while RegistryClient.uploadBlob() sends a fresh PUT to an absolute blob-upload Location supplied by the registry without checking that its origin or scheme matches the registry. A malicious or compromised registry can therefore direct a user pushing an artifact through attachArtifactToImage() to an attacker-controlled host and receive the registry bearer token, Basic credentials, or custom authentication headers. Redirect-time header stripping does not prevent the leak because the cross-host PUT is a new explicit request rather than a followed redirect. This is a residual of CVE-2026-59891, whose fix changed credential selection in credentials.ts but did not constrain where credentials are sent from registry.ts. Version 0.7.2 fixes the issue by separating registry credentials from client-wide defaults and sending them only to the registry origin.

Record
EUVD-2026-113272
CVSS 3.1
7.4 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-j63v-mwhm-56jx 7.4

@sigstore/oci sends the registry Authorization header to a cross-host blob-upload Location

Summary

@sigstore/oci sends the registry Authorization header to a cross-host blob-upload Location

Affected versions and vulnerable location

  • Confirmed on sigstore-js at 3a83271 (current HEAD).
  • File: packages/oci/src/registry.ts.
    • signIn() installs the credential as a DEFAULT header on the shared client: this.#fetch = this.#fetch.defaults({ headers: { [HEADER_AUTHORIZATION]: 'Basic ' + basicAuth } }) (:126-128) or ... 'Bearer ' + token (:145-147), plus creds.headers from the Docker config (:104).
    • uploadBlob() reads the Location response header (:184), builds uploadLocation = new URL(location.startsWith('/') ? this.#baseURL + location : location) (:190-192), and PUTs the blob to it through the same client: await this.#fetch(uploadLocation.href, { method: 'PUT', body: blob, headers: { [HEADER_CONTENT_TYPE]: ... } }) (:198).
  • There is no check that uploadLocation's host (or scheme) equals the registry host before the PUT is sent.

Root cause

Because signIn() sets Authorization via .defaults(), it is attached to every request the client issues, including requests to a host the client read out of a server response. When a POST to .../blobs/uploads/ returns an absolute Location pointing to a different host, uploadBlob() PUTs the blob there with the registry Authorization header still attached. If the challenge scheme was basic, that header carries the raw registry username:password; if bearer, it carries the access token; creds.headers custom auth headers ride along too.

The library's HTTP layer (make-fetch-happen / minipass-fetch) strips Authorization on cross-host redirects it follows internally, which protects the HEAD ... { redirect: 'follow' } at :167. It does not help here, because the PUT to the upload Location is a fresh, explicit this.#fetch() call, not a followed redirect, so the default header is applied unconditionally.

This is a residual of GHSA-pf56-329r-95rw / CVE-2026-59891 (credential confusion in @sigstore/oci). The fix for that advisory (commit 85c5838) changed only credentials.ts, replacing a key.includes(registry) substring match with an exact host match when SELECTING which Docker credential to load. It never touched registry.ts, which controls WHERE the loaded credential is sent. The cross-host send remains.

Attacker model

A user pushing a signed artifact/attestation to an OCI registry via attachArtifactToImage(). The credential leaks to any host the registry names in the blob-upload Location. This is reachable when the registry is malicious or compromised, or when a registry that legitimately redirects blob uploads to third-party storage is impersonated. The OCI distribution spec permits absolute upload Location values (registries commonly redirect blob storage to a separate host), so a compliant-but-hostile registry can steer the PUT to an attacker host and capture the credential. This is the same "attacker-controlled registry" threat model accepted for GHSA-pf56.

Reachability trace

index.ts:43 attachArtifactToImage() -> new OCIImage(...).addArtifact() -> image.ts:67 this.#client.signIn(credentials) (installs the default Authorization header) -> image.ts:76/79 this.#client.uploadBlob(...) -> registry.ts:198 PUT to the response-supplied Location with the default Authorization header attached. Same RegistryClient instance throughout, so the default persists.

Reproduction

Source-verified. No live push against a hostile registry was executed in this pass. Confirmed:

rg -n "defaults\(|HEADER_AUTHORIZATION|Location|new URL\(|this.#fetch\(uploadLocation" packages/oci/src/registry.ts
git log --oneline -3 -- packages/oci/src/credentials.ts packages/oci/src/registry.ts

signIn() sets Authorization via .defaults(); uploadBlob() PUTs to uploadLocation.href (which may be an absolute cross-host URL) with no host check; the GHSA-pf56 fix commit is the latest…

Record
GHSA-j63v-mwhm-56jx
CVSS 3.1
7.4 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N
Weakness
CWE-522
Updated
2026-11-02
NVD 7.4

sigstore-js provides JavaScript libraries for interacting with Sigstore services. Prior to 0.7.2, packages/oci/src/registry.ts contains a RegistryClient.signIn() method that stores registry Authorization and Docker configuration headers as defaults on a shared HTTP client, while RegistryClient.uploadBlob() sends a fresh PUT to an absolute blob-upload Location supplied by the registry without checking that its origin or scheme matches the registry. A malicious or compromised registry can therefore direct a user pushing an artifact through attachArtifactToImage() to an attacker-controlled host and receive the registry bearer token, Basic credentials, or custom authentication headers. Redirect-time header stripping does not prevent the leak because the cross-host PUT is a new explicit request rather than a followed redirect. This is a residual of CVE-2026-59891, whose fix changed credential selection in credentials.ts but did not constrain where credentials are sent from registry.ts. Version 0.7.2 fixes the issue by separating registry credentials from client-wide defaults and sending them only to the registry origin.

Record
CVE-2026-118763
CVSS 3.1
7.4 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N
Weakness
CWE-522
Updated
2026-11-02
OSV 7.4

@sigstore/oci sends the registry Authorization header to a cross-host blob-upload Location

sigstore-js provides JavaScript libraries for interacting with Sigstore services. Prior to 0.7.2, packages/oci/src/registry.ts contains a RegistryClient.signIn() method that stores registry Authorization and Docker configuration headers as defaults on a shared HTTP client, while RegistryClient.uploadBlob() sends a fresh PUT to an absolute blob-upload Location supplied by the registry without checking that its origin or scheme matches the registry. A malicious or compromised registry can therefore direct a user pushing an artifact through attachArtifactToImage() to an attacker-controlled host and receive the registry bearer token, Basic credentials, or custom authentication headers. Redirect-time header stripping does not prevent the leak because the cross-host PUT is a new explicit request rather than a followed redirect. This is a residual of CVE-2026-59891, whose fix changed credential selection in credentials.ts but did not constrain where credentials are sent from registry.ts. Version 0.7.2 fixes the issue by separating registry credentials from client-wide defaults and sending them only to the registry origin.

Record
CVE-2026-118763
CVSS 3.1
7.4 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N
Weakness
CWE-522
Updated
2026-11-02
OSVGHSA-j63v-mwhm-56jx 7.4

@sigstore/oci sends the registry Authorization header to a cross-host blob-upload Location

Summary

@sigstore/oci sends the registry Authorization header to a cross-host blob-upload Location

Affected versions and vulnerable location

  • Confirmed on sigstore-js at 3a83271 (current HEAD).
  • File: packages/oci/src/registry.ts.
    • signIn() installs the credential as a DEFAULT header on the shared client: this.#fetch = this.#fetch.defaults({ headers: { [HEADER_AUTHORIZATION]: 'Basic ' + basicAuth } }) (:126-128) or ... 'Bearer ' + token (:145-147), plus creds.headers from the Docker config (:104).
    • uploadBlob() reads the Location response header (:184), builds uploadLocation = new URL(location.startsWith('/') ? this.#baseURL + location : location) (:190-192), and PUTs the blob to it through the same client: await this.#fetch(uploadLocation.href, { method: 'PUT', body: blob, headers: { [HEADER_CONTENT_TYPE]: ... } }) (:198).
  • There is no check that uploadLocation's host (or scheme) equals the registry host before the PUT is sent.

Root cause

Because signIn() sets Authorization via .defaults(), it is attached to every request the client issues, including requests to a host the client read out of a server response. When a POST to .../blobs/uploads/ returns an absolute Location pointing to a different host, uploadBlob() PUTs the blob there with the registry Authorization header still attached. If the challenge scheme was basic, that header carries the raw registry username:password; if bearer, it carries the access token; creds.headers custom auth headers ride along too.

The library's HTTP layer (make-fetch-happen / minipass-fetch) strips Authorization on cross-host redirects it follows internally, which protects the HEAD ... { redirect: 'follow' } at :167. It does not help here, because the PUT to the upload Location is a fresh, explicit this.#fetch() call, not a followed redirect, so the default header is applied unconditionally.

This is a residual of GHSA-pf56-329r-95rw / CVE-2026-59891 (credential confusion in @sigstore/oci). The fix for that advisory (commit 85c5838) changed only credentials.ts, replacing a key.includes(registry) substring match with an exact host match when SELECTING which Docker credential to load. It never touched registry.ts, which controls WHERE the loaded credential is sent. The cross-host send remains.

Attacker model

A user pushing a signed artifact/attestation to an OCI registry via attachArtifactToImage(). The credential leaks to any host the registry names in the blob-upload Location. This is reachable when the registry is malicious or compromised, or when a registry that legitimately redirects blob uploads to third-party storage is impersonated. The OCI distribution spec permits absolute upload Location values (registries commonly redirect blob storage to a separate host), so a compliant-but-hostile registry can steer the PUT to an attacker host and capture the credential. This is the same "attacker-controlled registry" threat model accepted for GHSA-pf56.

Reachability trace

index.ts:43 attachArtifactToImage() -> new OCIImage(...).addArtifact() -> image.ts:67 this.#client.signIn(credentials) (installs the default Authorization header) -> image.ts:76/79 this.#client.uploadBlob(...) -> registry.ts:198 PUT to the response-supplied Location with the default Authorization header attached. Same RegistryClient instance throughout, so the default persists.

Reproduction

Source-verified. No live push against a hostile registry was executed in this pass. Confirmed:

rg -n "defaults\(|HEADER_AUTHORIZATION|Location|new URL\(|this.#fetch\(uploadLocation" packages/oci/src/registry.ts
git log --oneline -3 -- packages/oci/src/credentials.ts packages/oci/src/registry.ts

signIn() sets Authorization via .defaults(); uploadBlob() PUTs to uploadLocation.href (which may be an absolute cross-host URL) with no host check; the GHSA-pf56 fix commit is the latest…

Record
GHSA-j63v-mwhm-56jx
CVSS 3.1
7.4 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N
Weakness
CWE-522
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
@sigstore/oci
npm
through 0.7.1
0.7.2
@sigstore/oci
npm
before 0.7.2
0.7.2

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-118763 is a high vulnerability (CVSS 7.4) in Sigstore Sigstore-js, published October 29, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.30%, the 22nd percentile. Fixed in @sigstore/oci 0.7.2.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open