T09 · Insecure Skill Coding Practices
- Location
SKILL.md:837- Finding
Predictable Temporary File Permits Symlink Attacks and Retains Sensitive Batch Data
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 837-845
Vulnerability Type: Unsafe temporary-file handling
Risk Level: MediumVulnerable Code
python # Write JSONL file for batch submission batch_file = f"/tmp/batch_{int(time.time())}.jsonl" with open(batch_file, "w") as f: for task in self._queue: f.write(json.dumps(task) + "\n") # Upload and create batch with open(batch_file, "rb") as f: uploaded = self.client.files.create(file=f, purpose="batch")Technical Analysis
The batch filename is derived from the current Unix timestamp and placed directly in the shared
/tmpdirectory. This makes the path predictable and allows another local user to anticipate candidate filenames.The first
open()call uses ordinary write mode without exclusive creation, symlink rejection, or verification that the resulting file is a newly created regular file. On systems where symbolic links are followed, an attacker can pre-create the expected path as a symbolic link to another file. The process running this example would then truncate and overwrite the linked file with its own privileges.The file contains serialized batch tasks, including the complete
messagessupplied toenqueue(). These messages may contain prompts, conversation content, customer information, or other application data. The example does not delete the temporary file after upload, so this information can remain on disk beyond the required lifetime. Its readability depends on the process umask and host configuration.Attack Path
- An attacker with local access monitors the system clock and predicts a filename such as
/tmp/batch_1760000000.jsonl. - Before the victim calls
submit(), the attacker creates that path as a symbolic link to a file writable by the victim process. - The victim executes
open(batch_file, "w"), which follows the symbolic link. - The linked target is truncated and replac ...[truncated 1004 chars]
- An attacker with local access monitors the system clock and predicts a filename such as
- Remediation
View remediation
Remediation Suggestions
- Use Python's
tempfilemodule to generate an unpredictable, atomically created file. - Set restrictive permissions, ideally
0600, so only the creating account can read or write the file. - Delete the file in a
finallyblock immediately after the upload attempt. - Avoid reopening a path where possible; retain and reuse the securely created file descriptor.
- Ensure batch data is not written to disk at all when the client library supports in-memory streams.
Example hardening approach:
python import json import os import tempfile path = None try: with tempfile.NamedTemporaryFile( mode="w", encoding="utf-8", suffix=".jsonl", prefix="agent_batch_", delete=False, ) as tmp: path = tmp.name os.chmod(path, 0o600) for task in self._queue: tmp.write(json.dumps(task) + "\n") with open(path, "rb") as batch_stream: uploaded = self.client.files.create( file=batch_stream, purpose="batch", ) finally: if path is not None: try: os.unlink(path) except FileNotFoundError: pass- Use Python's
