Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-50163

CVE-2026-50163: oras-go Path Traversal Vulnerability

CVE-2026-50163 is a path traversal flaw in oras-go that allows attackers to expose or tamper with sensitive files like .env and .ssh/config. This article covers technical details, affected versions, and mitigation strategies.

Published:

CVE-2026-50163 Overview

CVE-2026-50163 is a path traversal vulnerability [CWE-22] in oras-go, a Go library for managing Open Container Initiative (OCI) artifacts. Versions prior to 2.6.2 contain a flaw in the ensureLinkPath function located in content/file/utils.go:262-275. The function validates a hardlink target against the extract base directory but returns the unresolved target, allowing os.Link to resolve the link name against the process current working directory rather than the extraction directory. An attacker who convinces a user to extract a crafted OCI artifact can create hardlinks to sensitive files outside the extraction root, exposing or tampering with data such as .env, .git/config, .aws/credentials, and ~/.ssh/config.

Critical Impact

Extracting a malicious OCI artifact with oras-go versions before 2.6.2 permits hardlink creation against arbitrary filesystem locations relative to the process CWD, exposing sensitive credentials and configuration files.

Affected Products

  • oras-go library versions prior to 2.6.2
  • Applications embedding oras-go for OCI artifact extraction with io.deis.oras.content.unpack: "true"
  • Downstream tools that invoke oras-go tar extraction logic

Discovery Timeline

  • 2026-07-17 - CVE-2026-50163 published to the National Vulnerability Database
  • 2026-07-23 - Last updated in NVD database

Technical Details for CVE-2026-50163

Vulnerability Analysis

The vulnerability arises during tar extraction of OCI artifacts marked for unpacking. When oras-go processes a tar entry with Typeflag=TypeLink, it calls ensureLinkPath to validate that the link target stays within the extraction base. The function performs the validation correctly but returns the original unresolved header.Linkname string rather than a path anchored to the extraction directory. The Linux link(2) syscall, invoked through os.Link, resolves relative paths against the process current working directory. This mismatch between validation context and syscall resolution context lets an attacker bypass the containment check.

A crafted tar entry with Name=payload.tar.gz/evil_cwd_link and Linkname="victim.secret" causes os.Link("victim.secret", "<extract_base>/payload.tar.gz/evil_cwd_link") to create a hardlink pointing to victim.secret in the CWD. Confidentiality impact is high because attackers can materialize hardlinks to credential files and read them through the extracted artifact tree.

Root Cause

The root cause is a Time-of-Check Time-of-Use inconsistency between path validation and hardlink creation. ensureLinkPath validates a resolved absolute form of the target against the extract base but returns the unresolved relative string. The os.Link call then re-resolves that string against the process CWD, defeating the validation.

Attack Vector

Exploitation requires user interaction: a victim must pull and extract an attacker-controlled OCI artifact using an oras-go-based client with unpack enabled. No authentication or privileges beyond artifact publishing are required. The attack vector is network-based because OCI artifacts are distributed through registries.

go
			// This is a known limitation and will not be addressed.
			var target string
			if target, err = ensureLinkPath(dirPath, dirName, filePath, header.Linkname); err == nil {
+				if !filepath.IsAbs(target) {
+					// link(2) resolves relative paths against the process CWD, not
+					// the link file's directory. Resolve explicitly to prevent escape.
+					target = filepath.Join(filepath.Dir(filePath), target)
+				}
				err = os.Link(target, filePath)
			}
		case tar.TypeSymlink:

Source: GitHub Commit c463c65

Detection Methods for CVE-2026-50163

Indicators of Compromise

  • Unexpected hardlinks inside OCI extraction directories pointing to sensitive files such as .env, .aws/credentials, or ~/.ssh/config
  • OCI artifact manifests carrying the annotation io.deis.oras.content.unpack: "true" from untrusted publishers
  • Tar entries with Typeflag=TypeLink where Linkname references paths outside the archive namespace

Detection Strategies

  • Inspect OCI artifacts before extraction using tar -tvf to enumerate hardlink entries and their targets
  • Audit dependency manifests (go.mod, go.sum) for oras.land/oras-go versions below 2.6.2
  • Compare inode numbers of files inside extraction directories against sensitive files in the process CWD to identify unauthorized hardlinks

Monitoring Recommendations

  • Log invocations of oras pull and equivalent library calls, capturing the working directory and artifact digest
  • Monitor filesystem telemetry for link() syscalls originating from oras-go-based processes targeting paths outside the extraction root
  • Alert on read access to credential files by processes handling OCI artifacts

How to Mitigate CVE-2026-50163

Immediate Actions Required

  • Upgrade oras-go to version 2.6.2 or later in all applications and CI/CD pipelines
  • Rotate any credentials that may have been exposed on systems that extracted untrusted OCI artifacts
  • Restrict OCI artifact pulls to trusted registries and signed publishers until upgrades complete

Patch Information

The fix is available in oras-go v2.6.2 via pull request #1232 and documented in GHSA-fxhp-mv3v-67qp. The patch resolves relative hardlink targets against the link file's directory before calling os.Link, aligning validation and syscall resolution contexts.

Workarounds

  • Disable the io.deis.oras.content.unpack behavior for artifacts from untrusted sources
  • Execute OCI extraction inside a dedicated working directory that contains no sensitive files
  • Run extraction inside a sandboxed container or chroot with a minimal filesystem to eliminate CWD-based hardlink targets
bash
# Update oras-go dependency to the patched version
go get oras.land/oras-go/v2@v2.6.2
go mod tidy

# Verify the resolved version
go list -m oras.land/oras-go/v2

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.