agentscope-ai / agentscope-ai/QwenPaw
[Question]: Should /api/files/preview/{filepath} allow arbitrary local file reads outside workspace and media boundaries?
- Dominant language
- Python
- Stars
- 34.9k
- Forks
- 3.1k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 225
Description
## Question or topic
Security concern: should `/api/files/preview/{filepath}` allow arbitrary absolute local file reads, or should it be restricted by workspace / media directory boundaries?
I found that the current implementation appears to allow any local file path to be resolved and returned directly. In practice, I was able to read local files outside the workspace boundary from the Console by visiting:
- `http://127.0.0.1:8088/api/files/preview//etc/hosts`
- `http://127.0.0.1:8088/api/files/preview//Users/yingchao/Documents/github/CoPaw/README.md`
Both returned file contents successfully.
From code inspection, the route in `src/copaw/app/routers/files.py` does:
- `Path(filepath)`
- convert to absolute path if needed
- `resolve()`
- return `FileResponse(...)` if `is_file()`
There does not appear to be any restriction to the current agent workspace, current agent media directory, or other trusted roots.
My question is whether this behavior is intentional, or whether it should be blocked by design. From a security perspective, this looks like arbitrary local file read and seems especially risky because it can be triggered directly from the browser URL.
## Context
- Project: CoPaw
- Local environment date: March 31, 2026
- Reproduced on local Console served at `http://127.0.0.1:8088`
- Tested via browser directly against the Console backend route
- Observed route: `/api/files/preview/{filepath}`
- Relevant file: `src/copaw/app/routers/files.py`
Why I’m asking:
- CoPaw now has multi-agent / multi-workspace isolation, so I expected file preview to stay within the current workspace or media directory.
- There are already related discussions around restricting local media paths to `media_dir`, so I’m not sure whether this endpoint is intentionally broader or just missing the same guardrails.
## Tried so far
- Reproduced directly in browser with absolute local paths
- Confirmed successful reads for:
- `/etc/hosts`
- repository files outside any attachment-specific boundary
- Inspected `src/copaw/app/routers/files.py` and saw that the route resolves and serves the requested path without checking workspace / media root membership
- Searched existing GitHub issues / PRs and found related discussions about media path validation and path boundary enforcement, but did not find one specifically describing `/api/files/preview` as an arbitrary local file read endpoint
---
Potential expectation if this is unintended:
- restrict preview to the current agent’s `workspace_dir` and/or `console` `media_dir`
- or replace raw path-based preview with an internal file ID / token mapping
- avoid serving arbitrary absolute filesystem paths directly from a global route
Contributor guide
Assessment
This issue has not been assessed yet.