T09 · Insecure Skill Coding Practices
- Location
scripts/cleanup_sessions.py:58- Finding
Non-Atomic Overwrite Can Corrupt the Session Index
- Content
View full analysis
Vulnerability Details
File Location:
scripts/cleanup_sessions.py, lines 58–59
Vulnerability Type: Non-atomic modification of a critical state file
Risk Level: MediumVulnerable Code
python with open(sessions_file, "w") as f: json.dump(data, f, indent=2)Technical Analysis
The script opens the active
sessions.jsonfile in write mode, which truncates the file before the updated JSON has been fully serialized and persisted. If the process is interrupted or the write fails because of an I/O error, exhausted disk space, or another exceptional condition, the live session index can be left empty or partially written.The implementation does not write through a temporary file, atomically replace the original, synchronize the completed write to disk, retain a backup, or provide a recovery path. This is an insecure coding practice when modifying a state file required by another application component.
Attack Path
- A user invokes the session cleanup script against an OpenClaw agent.
- The script loads the existing session index and determines which entries to remove.
- It opens the live
sessions.jsonwith mode"w", immediately truncating the file. - The process is terminated or the write fails before
json.dumpcompletes. - OpenClaw subsequently reads an empty, truncated, or malformed session index.
- Valid sessions may disappear from the interface, or session-state loading may fail until the index is restored.
This path primarily represents an availability and integrity failure. Exploitation would require the ability to interfere with the cleanup process or its storage environment; it does not grant additional operating-system privileges.
Impact Assessment
The issue affects the integrity and availability of the targeted OpenClaw agent's session index. Corruption may cause valid session records to be lost from the index, make sessions disappear from the webchat interface, or prevent the gateway from loadin ...[truncated 238 chars]
- Remediation
View remediation
Remediation Suggestions
Write the modified JSON to a uniquely named temporary file in the same directory as
sessions.json, then atomically replace the original only after the complete output has been successfully persisted.Recommended hardening steps:
- Create the temporary file securely in the destination directory, such as with
tempfile.NamedTemporaryFile. - Preserve the original file's ownership and permission mode where applicable.
- Serialize the complete JSON document to the temporary file.
- Flush Python's buffers and call
os.fsync()on the temporary file descriptor. - Optionally reopen and parse the temporary file to validate that it contains valid JSON.
- Replace the live index with
os.replace(), which is atomic when source and destination are on the same filesystem. - Synchronize the parent directory where durability guarantees are required.
- Retain a backup of the previous index or provide a restoration mechanism.
- Catch and report filesystem and serialization exceptions without modifying the original file.
- Consider file locking or coordination with the gateway to avoid concurrent updates and lost writes.
Example pattern:
python import os import tempfile parent = sessions_file.parent mode = sessions_file.stat().st_mode temp_path = None try: with tempfile.NamedTemporaryFile( mode="w", dir=parent, prefix=f".{sessions_file.name}.", suffix=".tmp", delete=False, ) as tmp: temp_path = Path(tmp.name) json.dump(data, tmp, indent=2) tmp.flush() os.fsync(tmp.fileno()) os.chmod(temp_path, mode) os.replace(temp_path, sessions_file) except Exception: if temp_path is not None: temp_path.unlink(missing_ok=True) raise- Create the temporary file securely in the destination directory, such as with
