T09 · Insecure Skill Coding Practices
- Location
scripts/rename-files.js:52- Finding
Unvalidated Prefix Allows Files to Be Moved Outside the Selected Directory
- Content
View full analysis
Vulnerability Details
File Location:
scripts/rename-files.js, lines 18, 52-55, and 82
Vulnerability Type: Path traversal in a filesystem destination
Risk Level: HighVulnerable Code
js const prefix = args[0];js const newName = prefix + baseName + extension; const oldPath = path.join(dirPath, oldName); const newPath = path.join(dirPath, newName);js fs.renameSync(op.oldPath, op.newPath);Technical Analysis
The command-line prefix is incorporated directly into
newNamewithout validating that it is a filename component. The resulting value is passed topath.joinand ultimately used as the destination offs.renameSync.A prefix containing parent-directory components, such as
../moved_, produces a normalized destination outside the selected directory. For example, processing/chosen/dir/file.txtwith that prefix constructs a destination equivalent to/chosen/moved_file.txt. The script therefore performs a file move rather than an in-directory rename.This contradicts the skill's declared behavior of adding a prefix to files in the selected directory. Although
SKILL.mdstates that the prefix should be sanitized if necessary, no such validation is implemented.Attack Path
- An attacker or mistaken user supplies a prefix containing traversal components, such as
../moved_. - The Agent invokes the script with that prefix and an otherwise valid target directory.
- The script concatenates the prefix with every file's base name.
path.joinnormalizes the resulting..component.fs.renameSyncmoves each affected file into the parent directory, provided that the process has the required filesystem permissions.- Additional traversal components can target other reachable directories where the destination path exists and is writable.
Impact Assessment
The vulnerability allows files selected by the script to be relocated outsid ...[truncated 516 chars]
- An attacker or mistaken user supplies a prefix containing traversal components, such as
- Remediation
View remediation
Remediation Suggestions
-
Treat the prefix strictly as a filename prefix rather than a path.
-
Reject prefixes containing
/,\, NUL,.., absolute-path syntax, drive prefixes, or platform-specific path separators. -
Prefer a conservative allowlist, such as letters, digits, spaces, underscores, and hyphens.
-
Resolve the selected directory and destination, then verify that the destination's parent is exactly the selected directory:
js const root = path.resolve(dirPath); if ( prefix.length === 0 || prefix.includes('\0') || prefix.includes('/') || prefix.includes('\\') || prefix === '..' || prefix.includes('../') || prefix.includes('..\\') ) { throw new Error('Prefix must be a plain filename prefix'); } const newName = prefix + baseName + extension; const newPath = path.resolve(root, newName); if (path.dirname(newPath) !== root) { throw new Error('Destination escapes the selected directory'); } -
Perform this containment check immediately before every rename rather than relying only on Agent-side input validation.
-
Include the fully resolved source and destination paths in the preview so that users can verify the actual filesystem effects.
-
