T09 · Insecure Skill Coding Practices
- Location
SKILL.md:110- Finding
Predictable Shared Temporary File Used for Price State
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 110-128
Vulnerability Type: Predictable temporary file and unsafe symlink following
Risk Level: MediumVulnerable Code:
python LAST_PRICE_FILE = "/tmp/last_price.json" def get_last_price(): """获取上次价格""" try: with open(LAST_PRICE_FILE) as f: return json.load(f)["price"] except: return None def save_price(price): """保存价格""" with open(LAST_PRICE_FILE, "w") as f: json.dump({"price": price}, f)Technical Analysis
The generated price-monitoring template stores persistent state at a fixed, predictable path in the shared
/tmpdirectory. The call toopen(LAST_PRICE_FILE, "w")follows symbolic links and truncates an existing destination before writing.On systems where temporary-directory symlink protections are absent, disabled, or inapplicable, another local user can prepare this pathname as a symbolic link to a file writable by the automation account. File-path collisions can also let another process corrupt the stored price. The unrestricted
exceptclause suppresses errors caused by malformed or attacker-controlled state, making interference harder to detect.Attack Path
- The attacker determines that the generated workflow uses
/tmp/last_price.json. - Before the first workflow run, the attacker creates that path as a symbolic link to another file writable by the automation account.
- The scheduled price monitor executes
save_price(). - Python follows the symbolic link and opens the linked target in truncating write mode.
- The target is overwritten with attacker-influenced workflow state, subject to the automation account's existing filesystem permissions.
Alternatively, an attacker able to manipulate the temporary file can insert malformed or false price state. This can suppress alerts, trigger misleading alerts, or cause the code to silently d ...[truncated 488 chars]
- The attacker determines that the generated workflow uses
- Remediation
View remediation
Remediation Suggestions
- Store persistent workflow state in a private application directory rather than
/tmp, such as~/.local/state/openclaw, with directory permissions set to0700. - Create state files with permissions no broader than
0600. - Refuse symbolic-link destinations by using platform-appropriate no-follow semantics, such as
os.open()withO_NOFOLLOWwhere supported. - Write to a securely created temporary file in the same private directory, flush and synchronize it, and atomically replace the destination with
os.replace(). - Validate that the destination is a regular file owned by the expected user before reading it.
- Replace the unrestricted
except:clause with specific exceptions such asFileNotFoundError,json.JSONDecodeError, andOSError, and log unexpected failures. - Use a unique state filename per workflow to prevent collisions.
- Store persistent workflow state in a private application directory rather than
