T09 · Insecure Skill Coding Practices
- Location
templates/clean.js:20- Finding
Destructive Allowlist-Based Cleanup Can Delete User Projects and Symlink Targets
- Content
View full analysis
rmRecurse(path.join(p, f))); fs.rmdirSync(p); } else { fs.unlinkSync(p); } } let removed = 0; for (const name of fs.readdirSync(ROOT)) { const p = path.join(ROOT, name); const isDir = fs.statSync(p).isDirectory(); if (isDir && KEEP_DIRS.has(name)) continue; if (!isDir && KEEP_FILES.has(name)) continue; console.log('rm', isDir ? `${name}/` : name); rmRecurse(p); removed++; } ``` The cleanup script is automatically executed after a successful ship: ```json "ship": "node record.js && node postprocess.js && node deploy.js && node review.js && node clean.js" ``` ### Technical Analysis The cleanup implementation treats every file or directory not included in a small allowlist as disposable. The Skill documentation instructs users to copy the templates into a user-selected working directory, which may be an existing application repository rather than a dedicated generated directory. Consequently, normal application files such as source directories, configuration files, documentation, tests, and version-control metadata can be recursively deleted when `npm run ship` reaches its cleanup phase. The use of `fs.statSync()` introduces an additional boundary issue because it follows symbolic links. If an unallowlisted entry is a symbolic link to a directory outside the workspace, the recursive function may traverse and delete content from the linked target rather than deleting only the link itself. ### Attack Path 1. The templates are copied into an existing application or repository directory. 2. The directory contains source files or folders not present i ...[truncated 999 chars]- Remediation
View remediation
