Skip to content

fix: reject path traversal in python entrypoints#2445

Merged
baszalmstra merged 1 commit into
conda:mainfrom
baszalmstra:claude/fix-vulnerability-YqeSJ
May 19, 2026
Merged

fix: reject path traversal in python entrypoints#2445
baszalmstra merged 1 commit into
conda:mainfrom
baszalmstra:claude/fix-vulnerability-YqeSJ

Conversation

@baszalmstra

Copy link
Copy Markdown
Collaborator

…points

`EntryPoint::FromStr` in `rattler_conda_types` previously only trimmed
whitespace before the linker joined `command` onto the install prefix
and wrote an executable Python script at `<prefix>/<bin_dir>/<command>`
(with `-script.py` / `.exe` siblings on Windows). A malicious
`noarch:python` package could ship `info/link.json` with an entry-point
name containing `..`, `/`, `\`, or an absolute path, causing the
resulting file to be written outside the prefix or clobber an
in-prefix entry-point such as `bin/pip`. The renderer also
interpolated `module` and `function` verbatim into the generated
script body, giving a second code-injection surface.

This change adds validation at two layers:

* `EntryPoint::FromStr` now validates `command` as a simple file name
  (rejecting empty strings, `/`, `\`, `\0`, `.`, `..`, leading `.`,
  and absolute paths) and `module` / `function` as Python dotted
  identifiers. Errors are returned via a typed `ParseEntryPointError`
  enum (with a companion `EntryPointDottedField`) instead of bare
  strings. Both are re-exported from `rattler_conda_types::package`.

* The install crate gains a `ValidatedRelativePath` newtype whose only
  constructor is `ensure_entry_point_relative_path`, which performs
  component-wise normalization and verifies that the resolved path
  stays under the install prefix. All filesystem-write helpers in
  `install::entry_point` (`write_validated_entry_point_file`,
  `write_validated_entry_point_bytes` for the Windows launcher, and
  `set_validated_entry_point_executable` for the Unix +x bit) take
  `&ValidatedRelativePath`, so the compiler rejects any call site
  that would reach a write without having run validation first.

Tested via new unit tests covering the traversal vectors from the
report (`../bin/pip`, absolute `/tmp/PWN`, Windows `..\..\..\`, hidden
names, NUL byte), code-injection attempts in `module`/`function`, and
realistic legitimate names (`jupyter-lab`, `pip3.11`, `pkg:Class.method`,
`_private`).

https://claude.ai/code/session_01RhMEEcinYyVNw9YtZTHqwR
@baszalmstra baszalmstra requested review from pavelzw and wolfv May 19, 2026 08:09
@baszalmstra baszalmstra changed the title fix: reject path traversal and code injection in noarch:python entry fix: reject path traversal in python entrypoints May 19, 2026
@baszalmstra baszalmstra merged commit 4f06eca into conda:main May 19, 2026
19 checks passed
@github-actions github-actions Bot mentioned this pull request May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants