fix(backend/copilot): add defence-in-depth realpath check in is_allowed_local_path

Resolve project_dir via os.path.realpath and validate it stays within
SDK_PROJECTS_DIR before checking the resolved path. Guards against
potential future bugs in _encode_cwd_for_cli, matching the pattern
already used in transcript.py.
This commit is contained in:
Zamil Majdy
2026-03-14 23:42:13 +07:00
parent 775ed85bba
commit 69db0815c3

View File

@@ -114,7 +114,10 @@ def is_allowed_local_path(path: str, sdk_cwd: str | None = None) -> bool:
encoded = _current_project_dir.get("")
if encoded:
project_dir = os.path.join(SDK_PROJECTS_DIR, encoded)
project_dir = os.path.realpath(os.path.join(SDK_PROJECTS_DIR, encoded))
# Defence-in-depth: ensure project_dir didn't escape the base.
if not project_dir.startswith(SDK_PROJECTS_DIR + os.sep):
return False
# Only allow: <encoded-cwd>/<uuid>/tool-results/<file>
# The SDK always creates a conversation UUID directory between
# the project dir and tool-results/.