oras-go: Arbitrary file write outside file.Store root via symlink-chain bypass in tar extraction (pushDir)
### Summary The `content/file.Store` in oras-go v2 unpacks OCI layer tarballs when a descriptor carries `io.deis.oras.content.unpack=true`. The extraction routine validates symlink targets purely lexically (`filepath.Join`) and, for regular files placed directly at the extraction root, skips the parent-symlink `Lstat` walk. A malicious tarball can plant a chain of symlinks whose lexical target stays inside the extraction root but whose kernel-resolved target is any absolute path, then write through it with a follow-up regular-file entry. The result is arbitrary file create/overwrite outside the store's working directory under the default `AllowPathTraversalOnWrite=false` configuration — a canonical tar-slip → RCE primitive. ### Details **Affected versions:** `<= v2.6.1` **Entry point:** `content/file/file.go` line 486, `(*Store).pushDir` — reached from `(*Store).Push` for any descriptor whose annotations include `io.deis.oras.content.unpack: "true"` (i.e. `file.AnnotationUnpack`) and an `org.opencontainers.image.title`. `oras.Copy` from a remote registry into a `file.New(dir)` store invokes this per layer. **Root cause 1 — lexical link validation.** `content/file/utils.go` lines 264–275, `ensureLinkPath`: ```go func ensureLinkPath(baseAbs, baseRel, link, target string) (string, error) { // resolve link path := target if !filepath.IsAbs(target) { path = filepath.Join(filepath.Dir(link), target) } // ensure path is under baseAbs or baseRel if _, err := resolveRelToBase(baseAbs,
GHSA-m37j-52j7-pjw7
Primary source · Revision 1
Imported from structured advisory data. Source references identify upstream records or fields; verify affected versions and your deployed configuration.
Security context
Source reference: osv:GHSA-m37j-52j7-pjw7
oras.land/oras-go/v2
Source reference: /affected/0/package/name
- Affected versions
- Not stated in this record
- Fixed versions
- 2.6.2
Source reference:
/affected/0/ranges - Prerequisites
- Not stated in this record
Structured affected-version data
Original package identities and version rules from this source.
[
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "0"
},
{
"fixed": "2.6.2"
}
]
}
],
"package": {
"name": "oras.land/oras-go/v2",
"purl": "pkg:golang/oras.land/oras-go/v2",
"ecosystem": "Go"
},
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-m37j-52j7-pjw7/GHSA-m37j-52j7-pjw7.json",
"last_known_affected_version_range": "<= 2.6.1"
}
}
]- Related CVEs
- CVE-2026-85731
Source reference:
/aliases
Publisher severity
high
Source reference: /database_specific/severity
- Event
- #63902 · Revision 1
- Added to Heist Feed
- Publisher date
GO-2026-6499
Revision 2
Arbitrary file write outside file.Store root via symlink-chain bypass in tar extraction (pushDir) in oras.land/oras-go
Arbitrary file write outside file.Store root via symlink-chain bypass in tar extraction (pushDir) in oras.land/oras-go
Imported from structured advisory data. Source references identify upstream records or fields; verify affected versions and your deployed configuration.
Security context
Source reference: osv:GO-2026-6499
oras.land/oras-go/v2
Source reference: /affected/0/package/name
- Affected versions
- Not stated in this record
- Fixed versions
- 2.6.2
Source reference:
/affected/0/ranges - Prerequisites
- Not stated in this record
Structured affected-version data
Original package identities and version rules from this source.
[
{
"ranges": [
{
"type": "SEMVER",
"events": [
{
"introduced": "0"
},
{
"fixed": "2.6.2"
}
]
}
],
"package": {
"name": "oras.land/oras-go/v2",
"purl": "pkg:golang/oras.land/oras-go/v2",
"ecosystem": "Go"
},
"database_specific": {
"source": "https://vuln.go.dev/ID/GO-2026-6499.json"
},
"ecosystem_specific": {}
}
]- Related CVEs
- CVE-2026-85731
Source reference:
/aliases
Publisher severity
No explicit severity was provided.
- Event
- #63903 · Revision 2
- Added to Heist Feed
- Publisher date