fix(security): confine tree_optimize --out/--log writes to allowed directories by rtmalikian · Pull Request #602 · VectifyAI/PageIndex · GitHub
Skip to content

fix(security): confine tree_optimize --out/--log writes to allowed directories - #602

Open
rtmalikian wants to merge 1 commit into
VectifyAI:mainfrom
rtmalikian:fix/584-cli-path-traversal
Open

rtmalikian wants to merge 1 commit into
VectifyAI:mainfrom
rtmalikian:fix/584-cli-path-traversal

Conversation

@rtmalikian

Copy link
Copy Markdown

Summary

--out and --log in pageindex/tree_optimize.py were passed straight to open(path, "w") with no validation, so an operator typo or an untrusted invocation could silently overwrite any user-writable file (e.g. --out /etc/cron.daily/x.json, --log ~/.ssh/authorized_keys).

The fix adds _confine_output_path(): it expands ~, resolves relative paths against the CWD (exactly as before), fully resolves the path (symlinks and .. normalized), and raises ValueError unless the result sits inside the current working directory or the input --structure directory. main() catches the error, prints a clean message to stderr, and exits non-zero (2). All previously legitimate flows are preserved: relative paths resolve under the CWD, the default <structure>.optimized.json lands next to the input, and absolute paths under either allowed directory still work.

Fixes #584

Changes

File Why
pageindex/tree_optimize.py New _confine_output_path() guard; main() validates --out and --log before any write, clean stderr error + exit 2 on escape
tests/test_tree_optimize_paths.py 7 new tests: relative/CWD resolution, absolute-under-allowed-dir, absolute-outside rejection, .. escape rejection, symlink escape rejection, union of CWD + structure dir, default out-path from --structure

Verification

  • python -m pytest tests/test_tree_optimize_paths.py -q — 7/7 pass (venv: PyPDF2, pyyaml, pytest, python-dotenv, regex, sortedcontainers).
  • Negative control: same tests against the pre-fix tree_optimize.py (via git stash) fail at collection (_confine_output_path does not exist), i.e. the guard is absent pre-fix.
  • Issue-repro simulation: _confine_output_path("/tmp/canary.txt", allowed_dirs=[cwd, struct_dir]) raises ValueError: --out: refusing to write outside ..., the canary file is untouched, and the default <structure>.optimized.json path still resolves fine.
  • Existing suite python -m pytest tests/test_tree_format.py -q — 30/30 pass (added pypdfium2 + litellm to the venv for collection); no regressions.
  • py_compile clean on both touched files. Repo CI runs plain pytest (no ruff/black config in pyproject.toml).

Author

Raphael Malikian — rtmalikian@gmail.com

If you would like similar help with your own project or codebase, I am open to collaborate — feel free to reach out.

This contribution was prepared with AI assistance.

…rectories

--out and --log were passed straight to open(path, 'w'), so a typo or an
untrusted invocation could silently overwrite any user-writable file
(e.g. --out /etc/cron.daily/x.json). _confine_output_path() resolves the
path (symlinks/.. normalized) and rejects anything outside the current
working directory or the input structure's directory; relative paths still
resolve under the CWD exactly as before. Fixes VectifyAI#584.

Signed-off-by: Raphael Malikian <rtmalikian@gmail.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-18T15:30:24.098799Z b7bf368 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] CLI path-traversal in tree_optimize.py --optimized / --log

1 participant