T05 · Unauthorized Access and Privilege Escalation
- Location
iteration_agent.py:246- Finding
Unrestricted Local File Read Through User-Controlled Paths
- Content
View full analysis
Vulnerability Details
File Location:
iteration_agent.py:246-258
Vulnerability Type: Arbitrary local file read
Risk Level: HighVulnerable Code
python def _tool_read(self, file_path: str) -> Dict: """读取文件工具""" path = Path(file_path) if not path.exists(): return {'error': '文件不存在'} if path.stat().st_size > 1024 * 1024: # 1MB限制 return {'error': '文件过大'} try: content = path.read_text(encoding='utf-8') return {'content': content[:1000]} # 限制返回长度 except Exception as e: return {'error': str(e)}Technical Analysis
The
file_pathparameter is controlled by the task caller and is converted directly into aPath. The implementation verifies only that the target exists and is no larger than 1 MB. It does not require the resolved path to remain within an authorized workspace, reject absolute paths, restrict symbolic links, or ensure the target is a regular file.Consequently, the
readtool can access any UTF-8-compatible file readable by the operating-system account running the agent. The write implementation has a current-directory boundary check, but no equivalent control is applied to reads.The one-thousand-character response limit reduces the amount disclosed by a single invocation but does not enforce access control. An attacker can target multiple files, and the implementation reads the entire accepted file into process memory before truncating the returned value.
Attack Path
- An attacker or untrusted task author creates a task step using the allowed
readtool. - The attacker supplies an absolute path or a relative traversal path pointing outside the intended workspace.
execute_tool()accepts the tool becausereadis on the allowlist._tool_read()opens the target without validating its location against an authorized root.- Up to the first 1,000 characters are returned to the calle ...[truncated 900 chars]
- An attacker or untrusted task author creates a task step using the allowed
- Remediation
View remediation
Remediation Suggestions
- Define an explicit workspace root instead of relying on unrestricted caller-provided paths.
- Resolve both the workspace and requested path before access, then require the requested path to be a descendant of the workspace.
- Reject absolute paths unless they have been explicitly authorized.
- Reject symbolic links or verify the final resolved target after following links.
- Require the target to be a regular file and reject device files, sockets, directories, and other special files.
- Consider an extension or file allowlist where tasks require only specific document types.
- Require explicit user confirmation before reading files outside the configured workspace.
- Apply the size limit before reading and use bounded or streaming reads so the full file is not loaded into memory.
- Add tests for absolute paths,
..traversal, symlink escapes, and workspace-prefix confusion.
A hardened design should use a pattern equivalent to:
python workspace = configured_workspace.resolve() requested = (workspace / file_path).resolve() if not requested.is_relative_to(workspace): return {'error': 'File is outside the authorized workspace'} if not requested.is_file() or requested.is_symlink(): return {'error': 'Target must be an authorized regular file'}
