T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/lib/storage.py:24
- Finding
- Schedule data files are created without enforced restrictive permissions## Vulnerability Details **File Location**: `scripts/init_storage.py:11-14`; `scripts/lib/storage.py:24-29` **Vulnerability Type**: Insecure local file permissions **Risk Level**: Medium ### Vulnerable Code `scripts/init_storage.py:11-14` ```python def write_json_if_missing(path, payload): if not os.path.exists(path): with open(path, "w", encoding="utf-8") as f: json.dump(payload, f, indent=2, ensure_ascii=False) ``` `scripts/lib/storage.py:24-29` ```python def _atomic_save(path, data): ensure_dir() tmp = path + ".tmp" with open(tmp, "w", encoding="utf-8") as f: json.dump(data, f, indent=2, ensure_ascii=False) os.replace(tmp, path) ``` ### Technical Analysis The Skill stores job titles, notes, tags, schedule metadata, and run information in JSON files under `~/.openclaw/workspace/memory/cron`. Both initial creation and subsequent atomic saves rely exclusively on process-default permissions. The code does not explicitly enforce mode `0600` on data files or mode `0700` on the storage directory. Consequently, the effective permissions depend on the caller's umask and existing parent-directory configuration. In an environment with a permissive umask, other local users may be able to read schedule data. Atomic updates create a new fixed-name temporary file and replace the destination with it. The replacement file inherits the temporary file's newly derived permissions rather than preserving a previously hardened destination mode. ### Attack Path 1. A user runs the Skill in an environment with a permissive umask or inadequately protected parent directories. 2. The user creates a schedule containing private information in its title, notes, tags, or timing metadata. 3. `init_storage.py` or `_atomic_save()` creates the corresponding JSON file without explicitly restrictive permissions. 4. Another local account examines `~/.openclaw/workspace/memory/cron`. ...[truncated 703 chars]
- Remediation
- ## Remediation Suggestions - Create the storage directory with mode `0700` and verify its ownership before use. - Create data and temporary files with mode `0600`, independent of the process umask. - Apply `os.chmod(path, 0o600)` to existing files after validating that they are owned by the expected user. - Use secure, exclusive temporary-file creation, such as `tempfile.mkstemp()` in the destination directory. - Flush and synchronize the temporary file before replacement when durability is required. - Verify that destination and temporary paths are regular files and are not unexpected symbolic links. - Preserve restrictive permissions across atomic replacements.
