T09 · Insecure Skill Coding Practices
- Location
references/deploy.mjs:172- Finding
Sensitive sibling files are uploaded without enforced confirmation
- Content
View full analysis
Vulnerability Details
File Location:
references/deploy.mjs:172-188, 412-426
Vulnerability Type: Unintended public disclosure of local files
Risk Level: HighComplete Code Snippet
js if ( existsSync(srcDir) && statSync(srcDir).isDirectory() && srcDir !== stagedDir && srcDir !== root ) { cpSync(srcDir, stagedDir, { recursive: true, filter: (s) => { const keep = !s.includes('node_modules') && !s.includes('.git') && !s.includes('__MACOSX') && !basename(s).startsWith('.') && s !== stagedDir; // guard against copying the staged dir into itself if (!keep) return false; if (!opts.assetsOnly) return true; // Directories still recurse; only files are filtered by type, and the // page itself is written separately below, so it can never be dropped. if (statSync(s).isDirectory()) return true; const kind = classifyStagedFile(basename(s)); if (kind === 'asset') return true; skipped.push({ path: relative(srcDir, s).split(sep).join('/'), kind }); return false; }, }); }js const { stagedDir, indexPath, files, skipped } = stageForDrop(htmlPath, pageExpiry, undefined, { assetsOnly: opts.assetsOnly, }); // Printed BEFORE the upload, on stderr, on every run — a review that only // appears when something is wrong cannot be distinguished from one that // failed to run at all. const note = opts.note || ((line) => console.error(line)); for (const line of stagingReview(files, { skipped })) note(line); const name = workerNameFrom(htmlPath, opts.name); const compatibilityDate = todayISO(); let protection; try { protection = opts.otp ? stageOtp(stagedDir, { name, compatibilityDate }) : null; const res = deployWithWrangler(stagedDir, {The corresponding behavior is explicitly documented in
SKILL.md:57-81:text This nev ...[truncated 2912 chars]- Remediation
View remediation
Remediation Suggestions
- Make allowlisted asset staging the default rather than recursively uploading all non-hidden files.
- Always exclude files classified as sensitive, including private-key formats, credential files, database backups, and environment/configuration secrets.
- If broad directory publication is required, stop before upload when flagged files are detected and require an explicit confirmation flag, such as
--include-flagged. - Bind confirmation to the reviewed staging manifest so files cannot be added or replaced between review and upload without invalidating approval.
- Print the complete upload manifest before confirmation and clearly distinguish intended static assets from unexpected or sensitive files.
- Preserve
--assets-onlybehavior but make it the secure default; provide an explicitly named opt-out only for users who intentionally need additional file types. - Add tests proving that recognized sensitive files cannot reach
deployWithWrangler()without explicit authorization.
