T09 · Insecure Skill Coding Practices
- Location
scripts/video_harness.py:220- Finding
Predictable Temporary Files Permit Symlink Overwrites and Response Data Exposure
- Content
View full analysis
Vulnerability Details
File Location:
scripts/video_harness.py, lines 220–225, 258–263, and 272–277
Vulnerability Type: Predictable and insecure temporary-file handling
Risk Level: MediumThe script writes API responses to fixed filenames in the shared system temporary directory:
python # Save response for debugging under system temp dir temp_dir = tempfile.gettempdir() resp_path = os.path.join(temp_dir, 'vertex_video_response.json') try: with open(resp_path, 'w', encoding='utf-8') as f: f.write(out) except Exception: passpython # Save intermediate poll log to system temp dir poll_path = os.path.join(temp_dir, 'vertex_video_operation_poll.json') try: with open(poll_path, 'w', encoding='utf-8') as f: f.write(out) except Exception: passpython final_path = os.path.join(temp_dir, 'vertex_video_operation_final.json') try: with open(final_path, 'w', encoding='utf-8') as f: f.write(json.dumps(pj)) except Exception: passTechnical Analysis
tempfile.gettempdir()commonly returns a shared directory such as/tmp. The files use constant, globally predictable names and are created with ordinaryopen(..., 'w').This operation:
- Follows symbolic links.
- Truncates an existing target before writing.
- Does not atomically reserve a unique pathname.
- Does not explicitly enforce owner-only permissions.
- Allows concurrent Skill runs to overwrite each other's response files.
- Leaves API responses and potentially base64-encoded video content behind after execution.
A local attacker who can create entries in the shared temporary directory may pre-create one of these predictable paths as a symbolic link. When the Skill runs under another account, Python may follow the link and overwrite a file writable by that victim account. Platform protections such as Linux protected-symlink settings may reduce ...[truncated 2120 chars]
- Remediation
View remediation
Remediation Suggestions
-
Remove response-debug file creation unless the user explicitly enables a debugging option.
-
Use a per-execution private temporary directory:
python with tempfile.TemporaryDirectory(prefix="vertex_video_") as temp_dir: resp_path = os.path.join(temp_dir, "response.json") -
If files must survive execution, create them atomically with
tempfile.NamedTemporaryFile(delete=False)ormkstemp()rather than constructing predictable names. -
Enforce owner-only permissions such as
0600. -
Do not follow symbolic links when opening an existing path. Where supported, use
os.open()withO_CREAT | O_EXCL | O_NOFOLLOW. -
Give each invocation and polling record a unique filename to prevent cross-run collisions.
-
Delete temporary response files in a
finallyblock when they are no longer needed. -
Avoid storing full response bodies when minimal metadata is sufficient. In particular, omit or redact generated base64 media content and sensitive error details from debug files.
-
Do not silently suppress all cleanup and write exceptions; report sanitized diagnostic errors so insecure or failed file handling can be detected.
-
