T09 · Insecure Skill Coding Practices
- Location
scripts/generate.js:13- Finding
Caller-Controlled Output Path Allows Arbitrary File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/generate.js, lines 13 and 27-33
Vulnerability Type: Unrestricted file write and unsafe path handling
Risk Level: MediumVulnerable 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
outputPathvalue 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
writeFileSyncwithout 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_fileargument passed to the script. The operation remains constrained by the filesystem privileges of the process running the Skill.Attack Path
- An attacker supplies QR content and a crafted
output_fileargument. - The argument identifies an existing writable file, an absolute path, a traversal path, or a symbolic link to another writable file.
- The script accepts the path without validating whether it is inside an authorized output directory.
- If the parent path does not exist and is writable,
mkdirSynccreates it recursively. writeFileSynctruncates the destination and replaces its contents with the generated PNG buffer.- The targeted file may become corrupte ...[truncated 660 chars]
- An attacker supplies QR content and a crafted
- Remediation
View remediation
Remediation Suggestions
- Place generated files in a dedicated, application-controlled output directory.
- Resolve both the approved directory and requested destination with
path.resolve, then verify that the destination remains within the approved directory. - Reject absolute paths, parent-directory traversal, and unexpected file extensions when arbitrary destination paths are unnecessary.
- Validate the final filename against a restrictive allowlist and require a
.pngextension. - Reject symbolic links in the destination path and verify path components before writing.
- Avoid silently replacing existing files. Use exclusive creation, such as the
wxflag, unless overwrite behavior has been explicitly authorized. - Run the Skill under a minimally privileged account with write access limited to its designated output directory.
- 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.
