T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/main.py:17
- Finding
- Predictable Home-Directory File Write Follows Symbolic Links and Uses Unrestricted Permissions## Vulnerability Details **File Location**: `scripts/main.py`, lines 17–18 and 29–30 **Vulnerability Type**: Unsafe persistent file handling **Risk Level**: Medium ### Vulnerable Code ```python def __init__(self, data_file="~/.openclaw/equipment_log.json"): self.data_file = Path(data_file).expanduser() self.data_file.parent.mkdir(parents=True, exist_ok=True) self.equipment = self._load() def _save(self): with open(self.data_file, 'w') as f: json.dump(self.equipment, f, indent=2) ``` ### Technical Analysis The application stores persistent equipment records at the predictable path `~/.openclaw/equipment_log.json`. The write operation uses Python's ordinary `open(..., 'w')`, which follows symbolic links and truncates an existing destination. The application does not verify that the destination is a regular file owned by the invoking user, reject symbolic links, perform an atomic replacement, or explicitly apply restrictive permissions such as `0600`. Consequently, an attacker who can manipulate the user's `~/.openclaw` directory or destination file could create a symbolic link from `equipment_log.json` to another file writable by the victim. When the victim adds an equipment record, the linked file would be truncated and replaced with JSON data. The resulting file permissions also depend on the process umask. Equipment names and locations may contain operationally sensitive information, so relying solely on the ambient umask could expose these records to other local users. This behavior also conflicts with the documentation's statement that output files are saved to the workspace: the implementation writes persistently to the user's home directory. ### Attack Path 1. A local attacker obtains the ability to create or replace `~/.openclaw/equipment_log.json`, such as through incorrectly configured directory permissions or prior access under the same account. 2. The attacker creates a symboli ...[truncated 1456 chars]
- Remediation
- ## Remediation Suggestions 1. Store records in a clearly documented, application-specific data directory with restrictive permissions rather than implicitly writing to an unrestricted home-directory path. 2. Create `~/.openclaw` with mode `0700` and the data file with mode `0600`, without relying exclusively on the process umask. 3. Reject symbolic-link destinations using `Path.is_symlink()` and perform secure descriptor-based checks immediately before writing to reduce time-of-check/time-of-use exposure. 4. Where supported, open files with `os.open()` using `O_NOFOLLOW`, `O_CREAT`, and an explicit restrictive mode. 5. Write to a securely created temporary file in the same directory, flush and synchronize it, and atomically replace the verified destination with `os.replace()`. 6. Before replacing an existing file, verify that it is a regular file and is owned by the expected user. 7. Validate the loaded JSON structure and handle malformed or attacker-modified records without exposing stack traces. 8. Update `SKILL.md` to accurately disclose the persistent home-directory write, or change the implementation so output is restricted to the documented workspace.
