Skip to content

cds get writes through destination symlinks #474

Description

@SemTiOne

Summary

cds get copies fetched files with shutil.copy2 (getter.py:76) and writes the tracking manifest with write_text (getter.py:571), both of which follow a symlink at the destination path.

Problem

_find_conflicts checks destination.exists() (getter.py:530). A dangling symlink returns False from Path.exists(), so a pre-placed symlink passes the conflict check without --force, and copy2 then creates the target file through the link. With --force, any symlink destination is overwritten through the link. A symlink planted at e.g. profiles/foo/profile.yaml -> ~/.ssh/config gets its target clobbered with fetched content. Shared working directories (CI workspaces, mounted home dirs) are the realistic attack surface.

Suggested fix

  • In _find_conflicts, treat destination.is_symlink() as a conflict regardless of target state.
  • Before copy2 and write_text, refuse (or unlink after confirming the target) any symlink destination.

Files involved

  • cli/getter.py (lines 74-76, 526-537, 570-571)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:securitySecurity policies and checksbugSomething isn't workingpriority:mediumHigh value but not blocking

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions