fix: restrict execute_code filenames to work_dir#3063
Conversation
There was a problem hiding this comment.
Pull request overview
This PR hardens dbgpt.util.code_utils.execute_code against path traversal by ensuring any model-provided # filename: is constrained to a resolved path within work_dir, preventing arbitrary file writes/execution outside the intended workspace.
Changes:
- Added
_resolve_work_dir_filepath()to validate filenames are relative and remain insidework_dirafter resolution (including symlink traversal). - Updated
execute_code()to use the validated resolved filepath instead ofos.path.join(work_dir, filename). - Added regression tests covering
..traversal, absolute paths, safe nested relative paths, and symlink escapes.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/dbgpt-core/src/dbgpt/util/code_utils.py | Enforces resolved filename paths remain within work_dir before writing/executing. |
| packages/dbgpt-core/src/dbgpt/util/tests/test_code_utils.py | Adds regression tests for traversal/absolute/symlink escape and a safe nested-path case. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks for the security fix! The path traversal protection is well-implemented with proper test coverage. A couple of notes:
Overall LGTM 👍 |
Updated this PR to address the two follow-up notes. Changes:
Local verification:
All local checks passed. One note on the current GitHub |
Summary
execute_codefilenames to resolved paths insidework_dirbefore writing or executing generated code.work_dir.Root Cause / 根因
CodeActioncan pass a model-generated# filename:header intoexecute_code. The previous implementation joinedwork_dirandfilenamedirectly, so a normalized path like../outside.pycould point outside the intended workspace before file creation.Validation / 测试
PYTHONPATH=packages/dbgpt-core/src .venv/bin/python -m pytest packages/dbgpt-core/src/dbgpt/util/tests/test_code_utils.py -qfailed withDID NOT RAISE ValueError.PYTHONPATH=packages/dbgpt-core/src .venv/bin/python -m pytest packages/dbgpt-core/src/dbgpt/util/tests/test_code_utils.py -q->3 passed.PYTHONPATH=packages/dbgpt-core/src .venv/bin/python -m pytest packages/dbgpt-core/src/dbgpt/util/tests -q->168 passed..venv/bin/ruff check packages/dbgpt-core/src/dbgpt/util/code_utils.py packages/dbgpt-core/src/dbgpt/util/tests/test_code_utils.py-> passed..venv/bin/ruff format --check packages/dbgpt-core/src/dbgpt/util/code_utils.py packages/dbgpt-core/src/dbgpt/util/tests/test_code_utils.py-> passed.git diff --check-> passed.../outside.pyis blocked and no outside file is created.Fixes #3025.
Fixes #3048.