fix(security): reject path-traversal in extra_info paths - #238
Conversation
An untrusted task's extra_info[].path was joined to the case dir with no containment check, so an absolute path or one containing '..' could copy arbitrary host files into the staged my-info dir (which can be shipped in a shareable Harbor export). Add validate_extra_info_path() — rejects absolute paths and any target whose resolved location escapes the task dir — and apply it in copy_extra_info. Valid relative paths are unchanged.
Perry2004
left a comment
There was a problem hiding this comment.
The new test case test_validate_extra_info_path_rejects_absolute is failing on Windows: https://github.com/TIGER-AI-Lab/ClawBench/actions/runs/28527654260/job/84568382985?pr=238
On Windows, Path('/etc/passwd').is_absolute() is False (no drive), so the guard
rejects it via the containment check ('escapes') rather than the is_absolute
branch ('absolute'). The path is still rejected (security holds); relax the
message match to 'absolute|escapes' so pytest (windows-latest) passes.
|
@Perry2004 Fixed — thanks for catching this. Root cause: on Windows Fixed in c5d8061 by relaxing the assertion to CI is now green on all OS including pytest (windows-latest): https://github.com/TIGER-AI-Lab/ClawBench/actions/runs/28944758766 Ready for re-review when you have a moment. |
Reject path-traversal in
extra_infopathsA task's
extra_info[].pathis untrusted input, butcopy_extra_info()joined it to the case dir with no containment check (src = task_dir / rel_path). An absolute path or one containing..could copy arbitrary host files into the stagedmy-info/dir — which is then shipped inside a shareable Harbor export (clawbench-harbor-adapt) or bind-mounted into the agent container. This is a real information-disclosure vector.Fix
validate_extra_info_path(task_dir, rel_path)inrun_support/task.py: rejects absolute paths and any target whose resolved location (symlinks followed) escapestask_dir(src.resolve().relative_to(task_dir.resolve())). Returns the unresolvedtask_dir / rel_path, so valid relative paths copy exactly as before.copy_extra_info()— benefits the native runner and the Harbor adapter, which both stageextra_info.Tests (all pass; ruff + pyright clean)
..escape rejected;copy_extra_infowith{"path": "../secret.txt"}raises and copies nothing.Small, self-contained, no behavior change for legitimate tasks. Found while building Harbor-runner tooling; extracted here as a standalone fix against
main.