Skip to content

fix(tools): keep notebook tool paths inside the project root - #118

Open
ElectLive wants to merge 1 commit into
knight22-21:mainfrom
ElectLive:fix/notebook-path-containment
Open

ElectLive wants to merge 1 commit into
knight22-21:mainfrom
ElectLive:fix/notebook-path-containment

Conversation

@ElectLive

Copy link
Copy Markdown

What does this PR do?

notebook_read, notebook_edit and notebook_run now resolve their path with file_tools._safe_resolve(), so a notebook outside the project root is rejected instead of read, written or executed.

Fixes #115

Root cause / motivation

All three tools did target = Path(project_root) / path and never checked the result, unlike file_tools, which has used _within_roots()/_safe_resolve() since the sibling-prefix fix. ../evil.ipynb and absolute paths such as /etc/passwd resolved outside the project.

notebook_run() made this an execution vector, not just a read: jupyter nbconvert --execute runs whatever the prompt points it at.

Changes

  • devagent/tools/notebook_tools.py: a small _resolve() helper wraps _safe_resolve(project_root, path) and returns [error] path escapes project root on a ValueError. All three tools call it before exists()/nbformat.read()/subprocess.run().
  • tests/test_notebook_tool_containment.py: notebook_read/notebook_edit/notebook_run all reject ../evil.ipynb, absolute outside paths are rejected, and a notebook inside the project still reads.

Test plan

pytest tests/test_notebook_tool_containment.py -q
.....                                                                    [100%]
5 passed in 0.83s

ruff check devagent/ tests/
All checks passed!

On the unmodified checkout the four containment tests fail (the outside notebook was read/edited, and notebook_run got as far as looking for jupyter), and they pass with the change.

  • python -m pytest tests/ -q passes (no new failures introduced) — ran the new module (5 passed); the full suite needs the optional provider SDKs and Jupyter installed, which this change does not touch
  • ruff check devagent/ tests/ is clean

Notes for reviewers

_safe_resolve() raises ValueError for a path outside the root, which is caught here and turned into the same [error] ... string shape the tools already return. --add-dir extra roots are not passed to the notebook tools; they only ever accepted the project root, so this restores exactly the intended behaviour rather than widening it.

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.

notebook_read/edit/run have no path traversal guard; arbitrary file read and RCE outside project root

1 participant