T09 · Insecure Skill Coding Practices
- Location
src/cli.mjs:359- Finding
Explicit Run Root Validation Can Be Bypassed with Symbolic Links and TOCTOU Replacement
- Content
View full analysis
0) { throw new Error(`--run-root must be empty or non-existent (refusing to write into a non-empty directory): ${resolved}`); } return resolved; } fs.mkdirSync(resolved, { recursive: true }); return resolved; } // Default path: collision-safe under runs/. const stamp = new Date().toISOString().replace(/[:]/g, '-').replace(/\.\d{3}Z$/, 'Z'); const slug = slugify(label || brief.slice(0, 60) || 'run'); fs.mkdirSync(DEFAULT_RUNS_DIR, { recursive: true }); const base = path.join(DEFAULT_RUNS_DIR, `${stamp}-${slug}`); ``` The associated validation only examines the lexical path: ```javascript function validateExplicitRunRoot(runRoot) { if (typeof runRoot !== 'string' || runRoot === '') { throw new Error('--run-root must be a non-empty path.'); } if (runRoot.includes('\0')) { throw new Error('--run-root contains a null byte.'); } const resolved = path.resolve(runRoot); if (resolved === '/' || resolved === '') { throw new Error('--run-root cannot be the filesystem root.'); } for (const prefix of FORBIDDEN_RUN_ROOT_PREFIXES) { if (resolved === prefix || resolved.startsWith(`${prefix}/`)) { throw new Error(`--run-root is inside a protected system path (${prefix}): ${resolved}`); } } return resolved; } ``` ### Technical Analysis `path.res ...[truncated 2728 chars]- Remediation
View remediation
