T05 · Unauthorized Access and Privilege Escalation
- Location
templates/project-scaffold/python/src/tools/file_tools.py:55- Finding
LLM-Invocable File Tools Allow Unrestricted Host Filesystem Access
- Content
View full analysis
Vulnerability Details
File Location:
templates/project-scaffold/python/src/tools/file_tools.py:55-76
Additional Locations:templates/project-scaffold/python/src/agent/core.py:55-63templates/project-scaffold/python/src/agent/core.py:96-101templates/project-scaffold/nodejs/src/tools/file_tools.js:43-69templates/project-scaffold/nodejs/src/agent/core.js:31-38templates/project-scaffold/nodejs/src/agent/core.js:54-59
Vulnerability Type: Unrestricted filesystem access and missing least-privilege enforcement
Risk Level: HighVulnerable Code
python def read_file(self, input_data: Dict[str, Any]) -> str: path = input_data["path"] offset = input_data.get("offset", 1) limit = input_data.get("limit", 2000) try: with open(path, 'r', encoding='utf-8') as f: lines = f.readlines() start = max(0, offset - 1) end = min(start + limit, len(lines)) return ''.join(lines[start:end]) except Exception as e: return f"Error: {str(e)}" def write_file(self, input_data: Dict[str, Any]) -> str: path = input_data["path"] content = input_data["content"] try: os.makedirs(os.path.dirname(path), exist_ok=True) with open(path, 'w', encoding='utf-8') as f: f.write(content) return f"Successfully wrote to {path}" except Exception as e: return f"Error: {str(e)}"The tools are registered by default and invoked directly from model-generated tool calls:
python self.tools.register("read_file", "Read file contents", file_tools.read_file_schema, file_tools.read_file) self.tools.register("write_file", "Write file contents", file_tools.write_file_schema, file_tools.write_file) self.tools.register("list_files", "List files", file_tools.list_files_schema, file_too ...[truncated 3582 chars]- Remediation
View remediation
Remediation Suggestions
-
Configure a fixed, canonical workspace root outside model control.
-
Resolve every requested path before access and verify that it remains beneath that root:
python workspace = Path(config.workspace_root).resolve() candidate = (workspace / requested_path).resolve(strict=False) try: candidate.relative_to(workspace) except ValueError: raise PermissionError("Path is outside the workspace") -
Reject absolute paths and explicit traversal components before resolution.
-
Protect against symbolic-link races by using descriptor-relative operations where supported and refusing symlinks for sensitive operations.
-
Maintain separate allowlists for readable and writable paths.
-
Deny access to
.env,.git, SSH directories, credential stores, session secrets, and security configuration even when they appear beneath the workspace. -
Require explicit user approval for writes, especially overwrites and writes to configuration or executable files.
-
Route every file operation through the permission model and sandbox rather than calling
ToolRegistry.execute()directly. -
Run the Agent as a dedicated low-privilege operating-system user inside an isolated container or equivalent sandbox.
-
Add tests for absolute paths,
../traversal, nested symlinks, broken symlinks, and race-condition attempts.
-
