T09 · Insecure Skill Coding Practices
- Location
skill.md:40- Finding
Predictable Temporary File and Symlink-Following Output Write
- Content
View full analysis
Vulnerability Details
File Location:
skill.md:40-41andgenerate_ppt.py:245
Vulnerability Type: Predictable temporary file and unsafe symlink-following file operation
Risk Level: MediumComplete Code Snippet:
bash OUTFILE="/tmp/popai_ppt_$(date +%s).jsonl" touch "$OUTFILE"python out = open(output_file, "a") if output_file else NoneTechnical Analysis
The documented workflow constructs an output pathname from the current timestamp in the shared
/tmpdirectory. The filename is predictable, andtouchdoes not ensure exclusive creation or verify that the path is a regular file owned by the invoking user.The Python implementation subsequently opens the caller-supplied path in append mode. Python's standard
open()follows symbolic links by default. It does not use exclusive creation,O_NOFOLLOW, ownership validation, or file-type validation.Consequently, another local user could pre-create the predicted path as a symbolic link or race to replace the touched file before the Python process opens it. The process would then append PopAI event output to the symlink target using the invoking user's filesystem privileges.
Attack Path
- An attacker with local access monitors or predicts when the documented workflow will run.
- The attacker derives the expected path, such as
/tmp/popai_ppt_<current_timestamp>.jsonl. - The attacker pre-creates that path as a symbolic link, or replaces the file after
touchand beforeopen(). - The link points to a target file writable by the victim account or to an attacker-controlled collection file.
- The Skill invokes
generate_ppt.pywith the predictable path through--output. open(output_file, "a")follows the symbolic link.- Parsed API events, summaries, presentation URLs, or attacker-influenced content are appended to the target.
Impact Assessment
Exploitation does not grant privileges beyond ...[truncated 618 chars]
- Remediation
View remediation
Remediation Suggestions
-
Replace timestamp-derived filenames with securely and atomically created temporary files:
bash OUTFILE="$(mktemp /tmp/popai_ppt.XXXXXXXXXX.jsonl)" chmod 600 "$OUTFILE" -
Prefer creating the file in Python with
tempfile.NamedTemporaryFile(delete=False)ortempfile.mkstemp(), which provides exclusive creation and a randomized name. -
Open user-supplied output paths with operating-system flags such as
O_NOFOLLOW,O_CREAT, and, when creating a new file,O_EXCL. -
Before writing, use
os.lstat()or equivalent checks to reject symbolic links and non-regular files. -
Verify that an existing output file is owned by the effective user and has restrictive permissions.
-
Keep the temporary file descriptor open from creation through use instead of creating a pathname and reopening it later, eliminating the time-of-check/time-of-use race.
-
Store temporary output in a private directory with mode
0700when possible.
-
