T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/figma_tool.py:108
- Finding
- Predictable Export Filename Allows File Clobbering and Symlink-Following Writes## Vulnerability Details **File Location**: `scripts/figma_tool.py`, lines 108–115 **Vulnerability Type**: Unprotected file overwrite and unsafe filename handling **Risk Level**: Medium ```python # Sanitize layer_id for filename safe_id = layer_id.replace(":", "_") filename = f"figma_export_{safe_id}.{args.format}" try: with urllib.request.urlopen(image_url) as response: with open(filename, "wb") as f: f.write(response.read()) print(f"Saved to {filename}") ``` ### Technical Analysis The export destination is predictable and is opened with `open(filename, "wb")`. This mode silently truncates existing files and follows symbolic links. The code neither checks whether the destination already exists nor ensures that it is a regular file inside a trusted export directory. Filename sanitization only replaces colon characters. It does not apply a strict character allowlist, reject path separators, normalize the resulting path, or verify that the resolved destination remains inside an authorized directory. A local attacker with write access to the working directory can prepare a symbolic link using the predictable export filename. When the Skill exports the corresponding layer, Python follows that link and overwrites its target with attacker-selected Figma image content. Exploitation remains limited by the filesystem permissions of the process running the Skill. This finding is separate from the expected network behavior. The audited code sends `FIGMA_TOKEN` only to the fixed official HTTPS Figma API endpoint, and it does not attach the token when downloading returned image URLs. That network access is necessary for the declared functionality and was not identified as credential exfiltration. ### Attack Path 1. An attacker obtains write access to the directory from which the Skill will run. 2. The attacker predicts the destination name from the layer ID and format, such as `figma_export_123_45 ...[truncated 1210 chars]
- Remediation
- ## Remediation Suggestions 1. Write exports into a dedicated directory whose ownership and permissions are controlled by the Skill. 2. Normalize layer identifiers using a strict allowlist, such as ASCII letters, digits, underscores, and hyphens. Reject path separators and special path components. 3. Resolve the final destination and verify that it remains within the intended export directory. 4. Create files atomically and exclusively using `open(path, "xb")`, or use `os.open` with `O_CREAT | O_EXCL` and, where supported, `O_NOFOLLOW`. 5. Refuse to overwrite existing files unless the user explicitly supplies an overwrite option. 6. Write to a securely created temporary file in the destination directory and atomically rename it only after a successful download. 7. Stream downloads in bounded chunks and enforce a maximum response size to reduce memory and disk-exhaustion risk. 8. Consider generating collision-resistant output names or requiring the caller to select an explicit, validated destination.
