{"id":"PYSEC-2026-1763","summary":"PDM Trojan Lockfile","details":"### Summary\nIt's possible to craft a malicious `pdm.lock` file that could allow e.g. an insider or a malicious open source project to appear to depend on a trusted PyPI project, but actually install another project.\n\n### Details\nProject `foo` can be targeted by creating the project `foo-2` and uploading the file `foo-2-2.tar.gz` to pypi.org. PyPI will see this as project `foo-2` version `2`, while PDM will see this as project `foo` version `2-2`. The version must only be [parseable as a version](https://github.com/frostming/unearth/blob/eca170d9370ac5032f2e497ee9b1b63823d3fe0f/src/unearth/evaluator.py#L215-L229) (and the filename must be a prefix of the project name), but it's [not verified to match the version being installed](https://github.com/pdm-project/pdm/blob/45d1dfa47d4900c14a31b9bb761e4c46eb5c9442/src/pdm/models/candidates.py#L98-L99). (Version `2-2` is also not a valid [normalized version per PEP 440](https://peps.python.org/pep-0440/#post-release-spelling).)\n\nMatching the project name exactly (not just prefix) would fix the issue. The version should also be verified to avoid version downgrade attacks.\n\n### PoC\nExample `pdm.lock` snippet to appear to depend on `foo` but actually install `foo-2`\n```\n\"foo 2.2.0\" = [\n  url = \"https://files.pythonhosted.org/.../foo-2-2.tar.gz\n]\n```\n\n### Impact\nWhen installing dependencies with PDM, what's actually installed could differ from what's listed in `pyproject.toml` (including arbitrary code execution on install). It could also be used for downgrade attacks by only changing the version.","aliases":["CVE-2023-45805","GHSA-j44v-mmf2-xvm9"],"modified":"2026-07-07T17:47:17.771927464Z","published":"2026-07-07T11:45:25.930514Z","references":[{"type":"WEB","url":"https://github.com/pdm-project/pdm/security/advisories/GHSA-j44v-mmf2-xvm9"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2023-45805"},{"type":"FIX","url":"https://github.com/pdm-project/pdm/commit/6853e2642dfa281d4a9958fbc6c95b7e32d84831"},{"type":"WEB","url":"https://github.com/frostming/unearth/blob/eca170d9370ac5032f2e497ee9b1b63823d3fe0f/src/unearth/evaluator.py#L215-L229"},{"type":"PACKAGE","url":"https://github.com/pdm-project/pdm"},{"type":"WEB","url":"https://github.com/pdm-project/pdm/blob/45d1dfa47d4900c14a31b9bb761e4c46eb5c9442/src/pdm/models/candidates.py#L98-L99"},{"type":"WEB","url":"https://peps.python.org/pep-0440/#post-release-spelling"},{"type":"PACKAGE","url":"https://pypi.org/project/pdm"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-j44v-mmf2-xvm9"}],"affected":[{"package":{"name":"pdm","ecosystem":"PyPI","purl":"pkg:pypi/pdm"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.10.0"}]}],"versions":["0.0.0","0.0.1","0.0.3","0.0.4","0.0.5","0.0.6","0.1.0","0.1.1","0.1.2","0.10.0","0.10.1","0.10.2","0.11.0","0.12.0","0.12.1","0.12.2","0.12.3","0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","0.2.6","0.3.0","0.3.1","0.3.2","0.4.0","0.4.1","0.4.2","0.5.0","0.6.0","0.6.1","0.6.2","0.6.3","0.6.4","0.6.5","0.7.0","0.7.1","0.8.0","0.8.1","0.8.2","0.8.3","0.8.4","0.8.5","0.8.6","0.8.7","0.9.0","0.9.1","0.9.2","1.0.0","1.0.0b0","1.0.0b2","1.1.0","1.10.0","1.10.1","1.10.2","1.10.3","1.11.0","1.11.1","1.11.2","1.11.3","1.12.0","1.12.1","1.12.2","1.12.3","1.12.4","1.12.5","1.12.6","1.12.7","1.12.8","1.13.0","1.13.0.post0","1.13.1","1.13.2","1.13.3","1.13.4","1.13.5","1.13.6","1.14.0","1.14.1","1.15.0","1.15.1","1.15.2","1.15.3","1.15.4","1.15.5","1.2.0","1.2.0.post1","1.3.0","1.3.1","1.3.2","1.3.3","1.3.4","1.4.0","1.4.1","1.4.2","1.4.3","1.4.4","1.4.5","1.5.0","1.5.0b0","1.5.0b1","1.5.1","1.5.2","1.5.3","1.6.0","1.6.1","1.6.2","1.6.3","1.6.4","1.7.0","1.7.1","1.7.2","1.8.0","1.8.1","1.8.2","1.8.3","1.8.4","1.8.5","1.9.0","2.0.0","2.0.0a1","2.0.0b1","2.0.0b2","2.0.1","2.0.2","2.0.3","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.5","2.2.0","2.2.1","2.3.0","2.3.1","2.3.2","2.3.3","2.3.4","2.4.0","2.4.1","2.4.2","2.4.3","2.4.4","2.4.5","2.4.6","2.4.7","2.4.8","2.4.9","2.5.0","2.5.0b0","2.5.1","2.5.2","2.5.3","2.5.4","2.5.5","2.5.6","2.6.0","2.6.1","2.7.0","2.7.1","2.7.2","2.7.3","2.7.4","2.8.0","2.8.0a0","2.8.0a1","2.8.0a2","2.8.1","2.8.2","2.9.0","2.9.1","2.9.2","2.9.3"],"database_specific":{"source":"https://github.com/pypa/advisory-database/blob/main/vulns/pdm/PYSEC-2026-1763.yaml"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"}]}