T09 · Insecure Skill Coding Practices
- Location
scripts/fetch_reviews.py:325- Finding
Predictable Temporary File Permits Symlink-Based File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/fetch_reviews.py, lines 325–327
Vulnerability Type: Predictable temporary file with unsafe symlink handling
Risk Level: MediumVulnerable Code
python output_path = f"/tmp/openreview_{forum_id}.json" with open(output_path, "w", encoding="utf-8") as f: json.dump(output, f, ensure_ascii=False, indent=2, default=str)Technical Analysis
The script writes its results to a predictable path in the shared
/tmpdirectory. The filename incorporates the user-suppliedforum_id, and the file is opened in write mode without exclusive creation or protection against symbolic-link traversal.Python's standard
open(..., "w")follows an existing symbolic link and truncates its target. A local attacker who can write to/tmpcan therefore create the expected output path as a symbolic link before the script runs. If the process has permission to write to the symlink target, the target is overwritten with JSON output.Exploitation requires local access to the shared temporary directory, knowledge or prediction of the forum ID, and the audited script running with write privileges over the selected target.
Attack Path
- Determine or predict the OpenReview forum ID that will be processed.
- Select a target file writable by the account under which the script will run.
- Create a symbolic link such as
/tmp/openreview_<forum_id>.jsonpointing to that target. - Wait for or induce the agent to execute
fetch_reviews.pywith the matching forum ID. - The script opens the predictable path in write mode, follows the symbolic link, truncates the target, and writes fetched JSON into it.
Impact Assessment
An attacker can overwrite or corrupt files writable by the script's effective user. Under an unprivileged account, impact is limited to files accessible to that account. If the skill runs under a privileged service account, the issue may cross privilege boundaries and damage ap ...[truncated 353 chars]
- Remediation
View remediation
Remediation Suggestions
- Use Python's
tempfilemodule to create an unpredictable file inside a private temporary directory with restrictive permissions. - If a deterministic destination is required, create it atomically with exclusive semantics and reject existing files.
- On supported platforms, use
os.openwithO_CREAT | O_EXCL | O_WRONLY | O_NOFOLLOW, then wrap the descriptor withos.fdopen. - Validate
forum_idagainst the expected OpenReview identifier format before using it in a filename. - Set restrictive permissions, such as mode
0o600, for generated files. - If results must be discoverable at a stable path, securely create a private per-user directory first and place the output there rather than directly in shared
/tmp. - Handle creation failures safely instead of deleting or replacing an unexpected existing path.
Example hardened approach:
python import os import re import tempfile if not re.fullmatch(r"[A-Za-z0-9_-]+", forum_id): raise ValueError("Invalid OpenReview forum ID") output_dir = tempfile.mkdtemp(prefix="openreview_") os.chmod(output_dir, 0o700) output_path = os.path.join(output_dir, f"{forum_id}.json") fd = os.open( output_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, "O_NOFOLLOW", 0), 0o600, ) with os.fdopen(fd, "w", encoding="utf-8") as f: json.dump(output, f, ensure_ascii=False, indent=2, default=str)- Use Python's
