T09 · Insecure Skill Coding Practices
- Location
scripts/cc-session-bridge.py:253- Finding
Arbitrary Filesystem Access Through Unvalidated Agent Name
- Content
View full analysis
str: sessions_dir = os.path.expanduser(f"~/.openclaw/agents/{agent_name}/sessions") return os.path.join(sessions_dir, MAP_FILE_NAME) ``` ```python def find_local_session(task_id: str, agent_name: str) -> tuple: """According to task_id find local session file, return (session_id, jsonl_path) or (None, None)""" mapping = load_task_session_map(agent_name) session_id = mapping.get(str(task_id)) if not session_id: return None, None sessions_dir = os.path.expanduser(f"~/.openclaw/agents/{agent_name}/sessions") jsonl_path = os.path.join(sessions_dir, f"{session_id}.jsonl") ``` ```python sessions_dir = os.path.expanduser(f"~/.openclaw/agents/{args.agent_name}/sessions") os.makedirs(sessions_dir, exist_ok=True) ``` ### Technical Analysis The caller-controlled `--agent-name` value is interpolated directly into filesystem paths. The code does not restrict the value to a safe agent-name syntax, resolve the resulting path to its canonical form, or verify that it remains beneath `~/.openclaw/agents`. An agent name containing traversal components such as `../` can therefore cause the session directory to resolve outside the intended agent storage hierarchy. The affected path is subsequently used for: - Directory creation through `os.makedirs`. - Reading and writing `task-session-map.json`. - Creating and appending session JSONL files. - Loading existing session mappings. - Following filesystem symbolic links without validation. Although generated session file names are UUID-based, an attacker can still direct their creation into an unintended directory. If the attacker can prepare a mapping file or symbolic link at the resolved location, the app ...[truncated 1463 chars]- Remediation
View remediation
str: if not AGENT_NAME_PATTERN.fullmatch(agent_name): raise ValueError("Invalid agent name") return agent_name ``` 2. Resolve and enforce canonical path containment: ```python base_dir = os.path.realpath(os.path.expanduser("~/.openclaw/agents")) sessions_dir = os.path.realpath( os.path.join(base_dir, validate_agent_name(agent_name), "sessions") ) if os.path.commonpath([base_dir, sessions_dir]) != base_dir: raise ValueError("Agent session path escapes the allowed directory") ``` 3. Reject symbolic links in sensitive path components and mapping/session files. Where supported, use file descriptors with `O_NOFOLLOW`. 4. Write mapping files atomically by creating a securely permissioned temporary file in the same directory, calling `fsync`, and replacing the destination with `os.replace`. 5. Create session directories and files with restrictive permissions, such as directory mode `0700` and file mode `0600`. 6. If the application has a registry of valid agents, require `--agent-name` to match an existing authorized agent rather than accepting arbitrary names. ]]>
