CVE-2026-34591
Description
Poetry is a dependency manager for Python. From version 1.4.0 to before version 2.3.3, 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. It is reachable from untrusted package artifacts during normal install flows. (Normally, installing a malicious wheel is not sufficient for execution of malicious code. Malicious code will only be executed after installation if the malicious package is imported or invoked by the user.). This issue has been patched in version 2.3.3.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
poetryPyPI | >= 1.4.0, < 2.3.3 | 2.3.3 |
Affected products
1Patches
1ed59537ac370installer: fix path traversal (#10792)
2 files changed · +56 −1
src/poetry/installation/wheel_installer.py+8 −1 modified@@ -44,7 +44,14 @@ def write_to_fs( from installer.utils import copyfileobj_with_hashing from installer.utils import make_file_executable - target_path = Path(self.scheme_dict[scheme]) / path + target_dir = Path(self.scheme_dict[scheme]).resolve() + target_path = (target_dir / path).resolve() + + if not target_path.is_relative_to(target_dir): + raise ValueError( + f"Attempting to write {path} outside of the target directory" + ) + if target_path.exists(): # Contrary to the base library we don't raise an error here since it can # break pkgutil-style and pkg_resource-style namespace packages.
tests/installation/test_wheel_installer.py+48 −0 modified@@ -81,3 +81,51 @@ def test_enable_bytecode_compilation( assert not list(cache_dir.glob("*.opt-2.pyc")) else: assert not cache_dir.exists() + + +def test_install_dir_is_symlink(tmp_path: Path, demo_wheel: Path) -> None: + target_dir = tmp_path / "target" + target_dir.mkdir() + symlink_dir = tmp_path / "symlink" + symlink_dir.symlink_to(target_dir, target_is_directory=True) + + env = MockEnv(path=symlink_dir) + + installer = WheelInstaller(env) + installer.install(demo_wheel) + + assert (Path(env.paths["purelib"]) / "demo").exists() + + +@pytest.fixture +def wheel_with_path_traversal(tmp_path: Path) -> Path: + import zipfile + + wheel = tmp_path / "traversal-0.1-py3-none-any.whl" + files = { + "traversal/__init__.py": b"", + "../../traversal.txt": b"", + "traversal-0.1.dist-info/WHEEL": ( + b"Wheel-Version: 1.0\nRoot-Is-Purelib: true\nTag: py3-none-any\n" + ), + "traversal-0.1.dist-info/METADATA": ( + b"Metadata-Version: 2.1\nName: traversal\nVersion: 0.1\n" + ), + } + files["traversal-0.1.dist-info/RECORD"] = ( + "\n".join([f"{k},," for k in files] + ["traversal-0.1.dist-info/RECORD,,"]) + + "\n" + ).encode() + + with zipfile.ZipFile(wheel, "w") as z: + for k, v in files.items(): + z.writestr(k, v) + + return wheel + + +def test_path_traversal(env: MockEnv, wheel_with_path_traversal: Path) -> None: + installer = WheelInstaller(env) + with pytest.raises(ValueError): + installer.install(wheel_with_path_traversal) + assert not (env.path.parent / "traversal.txt").exists()
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/python-poetry/poetry/commit/ed59537ac3709cfbdbf95d957de801c13872991anvdPatchWEB
- github.com/python-poetry/poetry/pull/10792nvdIssue TrackingPatchWEB
- github.com/python-poetry/poetry/security/advisories/GHSA-2599-h6xx-hpxpnvdExploitVendor AdvisoryWEB
- github.com/advisories/GHSA-2599-h6xx-hpxpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-34591ghsaADVISORY
- github.com/python-poetry/poetry/releases/tag/2.3.3nvdProductRelease NotesWEB
News mentions
7- SecurityScorecard Snags Driftnet to Level Up Threat IntelligenceDark Reading · May 14, 2026
- AWS to Quick admins: The access control didn't work, but you weren't using it anyway, so what's the problem?The Register Security · May 13, 2026
- Checkbox Assessments Aren't Fit to Measure RiskDark Reading · May 13, 2026
- Research Hub Bridges Cybersecurity Gap for Under-Resourced OrganizationsDark Reading · May 5, 2026
- Oracle Red Bull Racing Team Revs Up Automation to Boost SecurityDark Reading · Apr 30, 2026
- Electricity Is a Growing Area of Cyber-RiskDark Reading · Apr 22, 2026
- Orchestrating AI Code Review at scaleCloudflare Blog · Apr 20, 2026