T09 · Insecure Skill Coding Practices
- Location
scripts/lib/storage.py:24- Finding
Schedule data files are created without enforced restrictive permissions
- Content
View full analysis
Vulnerability Details
File Location:
scripts/init_storage.py:11-14;scripts/lib/storage.py:24-29
Vulnerability Type: Insecure local file permissions
Risk Level: MediumVulnerable Code
scripts/init_storage.py:11-14python 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-29python 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
0600on data files or mode0700on 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
- A user runs the Skill in an environment with a permissive umask or inadequately protected parent directories.
- The user creates a schedule containing private information in its title, notes, tags, or timing metadata.
init_storage.pyor_atomic_save()creates the corresponding JSON file without explicitly restrictive permissions.- Another local account examines
~/.openclaw/workspace/memory/cron.
...[truncated 703 chars]
- Remediation
View remediation
Remediation Suggestions
- Create the storage directory with mode
0700and 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.
- Create the storage directory with mode
