T09 · Insecure Skill Coding Practices
- Location
bin/cli.js:429- Finding
Unrestricted File Overwrite Through Export Path
- Content
View full analysis
Vulnerability Details
File Location:
bin/cli.js:429-434
Vulnerability Type: Arbitrary file overwrite
Risk Level: MediumVulnerable Code
js function handleExport(fl, options) { const format = options.format || 'json'; const data = fl.exportData(format); if (options.output) { fs.writeFileSync(options.output, data); console.log(`Data exported to ${options.output}`); } else { console.log(data); } }Technical Analysis
The CLI passes the user-controlled
--outputargument directly tofs.writeFileSync. The destination is not canonicalized or restricted to an approved export directory, and the implementation does not check whether the destination already exists or is a symbolic link.fs.writeFileSynctruncates an existing destination by default. Consequently, any process or user able to invoke the CLI can replace arbitrary files writable by that process. This is particularly relevant when an AI Agent constructs the command from untrusted instructions or runs the Skill under an account with access to important workspace or user configuration files.The vulnerability does not independently escalate operating-system privileges. Its reach is limited to paths writable by the invoking account.
Attack Path
- An attacker causes a user or Agent to invoke the export command with a crafted destination:
bash feedback-loop export --format json --output /path/to/writable/important-file parseArgsstores the attacker-selected path inoptions.output.handleExportgenerates the export content.fs.writeFileSync(options.output, data)opens the selected file for writing and truncates it.- The original file is replaced with exported JSON or CSV content, potentially corrupting configuration, application data, workspace content, or user startup files.
A symbolic link located at an apparently safe destination could also redirect the write to another writable target.
Impact Assess
...[truncated 641 chars]
- An attacker causes a user or Agent to invoke the export command with a crafted destination:
- Remediation
View remediation
Remediation Suggestions
- Resolve the requested path with
path.resolveand require it to remain inside a dedicated export directory. - Reject absolute paths and traversal components unless arbitrary destinations are an explicit, trusted administrative feature.
- Use
fs.lstatSyncto reject symbolic links and validate each relevant parent directory where the threat model includes untrusted local filesystem content. - Prevent replacement by default using exclusive creation:
js fs.writeFileSync(validatedPath, data, { encoding: 'utf8', flag: 'wx' }); - Require an explicit
--forceoption and confirmation before overwriting an existing regular file. - Document that export destinations must be trusted and run the Skill with least-privilege filesystem permissions.
- Add tests covering absolute paths,
../traversal, existing files, symbolic links, and destinations outside the approved export directory.
- Resolve the requested path with
