T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/generate.js:13
- Finding
- Caller-Controlled Output Path Allows Arbitrary File Overwrite## Vulnerability Details **File Location**: `scripts/generate.js`, lines 13 and 27-33 **Vulnerability Type**: Unrestricted file write and unsafe path handling **Risk Level**: Medium ### Vulnerable Code ```javascript // Default output path const output = outputPath || path.join(process.cwd(), 'qrcode.png'); // Ensure directory exists const dir = path.dirname(output); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } // Write file fs.writeFileSync(output, buffer); ``` ### Technical Analysis The optional `outputPath` value comes directly from the second command-line argument and is used as a filesystem destination without canonicalization, directory restrictions, traversal validation, symbolic-link checks, or confirmation before overwriting an existing file. Absolute paths and paths containing parent-directory components are accepted. The script also creates missing directories recursively and calls `writeFileSync` without an exclusive-create flag. Consequently, any existing writable target is truncated and replaced with PNG data. A symbolic link supplied as the destination can cause the write to follow the link and modify its target. Exploitation requires an attacker to control or influence the `output_file` argument passed to the script. The operation remains constrained by the filesystem privileges of the process running the Skill. ### Attack Path 1. An attacker supplies QR content and a crafted `output_file` argument. 2. The argument identifies an existing writable file, an absolute path, a traversal path, or a symbolic link to another writable file. 3. The script accepts the path without validating whether it is inside an authorized output directory. 4. If the parent path does not exist and is writable, `mkdirSync` creates it recursively. 5. `writeFileSync` truncates the destination and replaces its contents with the generated PNG buffer. 6. The targeted file may become corrupte ...[truncated 660 chars]
- Remediation
- ## Remediation Suggestions 1. Place generated files in a dedicated, application-controlled output directory. 2. Resolve both the approved directory and requested destination with `path.resolve`, then verify that the destination remains within the approved directory. 3. Reject absolute paths, parent-directory traversal, and unexpected file extensions when arbitrary destination paths are unnecessary. 4. Validate the final filename against a restrictive allowlist and require a `.png` extension. 5. Reject symbolic links in the destination path and verify path components before writing. 6. Avoid silently replacing existing files. Use exclusive creation, such as the `wx` flag, unless overwrite behavior has been explicitly authorized. 7. Run the Skill under a minimally privileged account with write access limited to its designated output directory. 8. Handle directory creation and file creation defensively to reduce time-of-check/time-of-use risks; where supported, use file-opening mechanisms that prevent following symbolic links.
