chore(deps): update dependency pdm to v2.27.0 [security]#1602
Open
renovate[bot] wants to merge 1 commit into
Open
chore(deps): update dependency pdm to v2.27.0 [security]#1602renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
1daa7fd to
30df2a7
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
c3efad2 to
743a2b3
Compare
743a2b3 to
ae599fd
Compare
ae599fd to
56fc19b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
==2.26.9→==2.27.0PDM: Project-Local State and Config Writes Follow Symlinks
CVE-2026-47763 / GHSA-ghq2-5c67-fprm
More information
Details
Summary
PDM writes several project-local state or configuration files without symlink protection. If a malicious repository places those files as symlinks, local PDM operations can overwrite the symlink targets.
This creates an arbitrary file clobber primitive relative to the privileges of the invoking user.
Affected Behavior
pdm.toml.pdm-pythonand.python-versionAffected Code
src/pdm/project/config.py:303-350src/pdm/project/core.py:209-217src/pdm/cli/commands/use.py:187-189Technical Details
Config.__init__()resolves the project-localpdm.tomlpath and_save_config()writes to the resolved target. IfPROJECT_ROOT/pdm.tomlis a symlink to another file,pdm config -l ...updates the target file instead of refusing the write.The same general problem exists for other project-local persistence paths that are written directly with no
lstat/O_NOFOLLOWprotection.For the
pdm.tomlPoC specifically, the target file must already contain parseable TOML. Otherwise the load step fails before the write path is reached. That parser constraint does not apply to the.pdm-pythonor.python-versionsinks.Impact
pdmis run in elevated contextsReproduction
PoC:
Expected result:
pdm.tomlis a symlink to another TOML filepdm config -l venv.in_project falsemodifies the symlink targetObserved output from local validation:
Severity
Medium
CVSS v4.0
6.8(Medium)CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:H/VA:L/SC:N/SI:N/SA:NRationale:
AV:L: exploitation requires local execution ofpdmagainst an attacker-prepared checkoutAC:L: there is no complex constraint once the symlink sink existsAT:N: no extra prerequisite beyond the victim running the relevant command is requiredPR:N: the attacker does not need prior privileges on the victim systemUI:A: the victim must actively run a command that writes project-local state or configVC:N: the demonstrated issue is a write primitive, not a direct read primitiveVI:H: the attacker can cause unauthorized modification of files outside the repository rootVA:L: file clobber can disrupt local operation, but direct same-step availability impact is lower than a full RCESC:N/SI:N/SA:N: the base score is limited to the directly affected systemRoot Cause
Project-local file sinks are treated as trusted regular files and are written without symlink checks or guarded atomic replacement.
Recommended Remediation
lstatandO_NOFOLLOWwhere availableDisclosure Notes
This issue is independent from the code-execution issues above. It is best tracked as a separate CVE candidate because the root cause and remediation are different.
Severity
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:H/VA:L/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
PDM: Project-Controlled
.pdm-pluginsContent Executes Before CLI ParsingCVE-2026-47781 / GHSA-qq6c-99pv-prvf
More information
Details
Summary
PDM automatically loads project-local plugin paths from
.pdm-pluginsduringCoreinitialization. Because this path is added viasite.addsitedir(), attacker-controlled.pthfiles inside the project plugin directory are processed and can execute Python code before normal CLI handling begins.This allows arbitrary code execution with the privileges of the user running
pdmfrom an untrusted repository checkout.Affected Behavior
pdm install --pluginspdm --versionis sufficientAffected Code
src/pdm/core.py:74-82src/pdm/core.py:310-333src/pdm/core.py:335-352Technical Details
Core.__init__()callsload_plugins()before ordinary command execution.load_plugins()calls_add_project_plugins_library(), which derives the project-local.pdm-pluginslibrary path and adds it throughsite.addsitedir().On CPython,
site.addsitedir()processes.pthfiles found in the added directory..pthlines beginning withimportare executed immediately. This creates a trust-boundary break: project-controlled files execute before the user explicitly opts into plugin installation or plugin loading.Impact
pdmis run viasudo, root-owned CI jobs, or privileged service accountsReproduction
PoC:
Expected result:
evil.pthfile is placed under.pdm-pluginspdm --versioncreates a marker file before CLI exitObserved output from local validation:
Severity
High
CVSS v4.0
8.4(High)CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:NRationale:
AV:L: exploitation occurs through local execution ofpdmagainst attacker-controlled repository contentAC:L: no special bypass or race is requiredAT:N: no external precondition beyond the vulnerable workflow is requiredPR:N: the attacker does not need privileges on the victim hostUI:A: the victim must actively run apdmcommand in the malicious checkoutVC:H/VI:H/VA:H: successful exploitation yields arbitrary code execution as the invoking userSC:N/SI:N/SA:N: the score is kept to same-system impact onlyRoot Cause
Project-local plugin paths are implicitly trusted and loaded too early, and
.pthprocessing is inherited fromsite.addsitedir().Recommended Remediation
.pdm-pluginsby defaultsite.addsitedir()for project-controlled plugin paths--enable-project-plugins.pthexecution when loading project plugin pathsDisclosure Notes
This issue is a strong standalone CVE candidate because it yields direct code execution from repository-controlled files without requiring the victim to run a project script explicitly.
Severity
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
pdm-project/pdm (pdm)
v2.27.0Compare Source
Breaking Changes
Features & Improvements
pyproject.tomlwhen runningpdm initorpdm new. (#3786).pdm-pluginsunder the project root to an isolated cache directory, and add a fixer to migrate existing plugin directories. (#3790)importlib.metadataandimportlib.resourcesAPIs directly. (#3796)Bug Fixes
pdm.toml,.pdm-python,.python-version) when the destination is a symlink, preventing an untrusted repository from clobbering files outside the project root. (#3788)PDM_LOCKFILEenv var is not respected. (#3794)--exclude-newervalue withstrategy.exclude-newer. (#3795)Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.