T09 · Insecure Skill Coding Practices
- Location
scripts/imap.js:14- Finding
Attachment download write allowlist can be bypassed through symbolic links
- Content
View full analysis
path.resolve(d.replace(/^~/, os.homedir())) ); const allowed = allowedDirs.some(dir => resolved === dir || resolved.startsWith(dir + path.sep) ); if (!allowed) { throw new Error(`Access denied: '${dirPath}' is outside allowed write directories`); } return resolved; } ``` ```javascript // Create output directory if it doesn't exist const resolvedDir = validateWritePath(outputDir); if (!fs.existsSync(resolvedDir)) { fs.mkdirSync(resolvedDir, { recursive: true }); } const downloaded = []; for (const attachment of parsed.attachments) { // If specificFilename is provided, only download matching attachment if (specificFilename && attachment.filename !== specificFilename) { continue; } if (attachment.content) { const filePath = path.join(resolvedDir, sanitizeFilename(attachment.filename)); fs.writeFileSync(filePath, attachment.content); ``` ### Technical Analysis The write allowlist compares only lexically resolved paths. `path.resolve()` normalizes path components but does not resolve symbolic links. Consequently, a path can appear to be beneath an allowed directory while its actual filesystem destination is outside that directory. Although `sanitizeFilename()` prevents direct filename traversal using `../`, it does not protect against a symbolic link in the destination path. `fs.writeFileSync()` follows symbolic links and overwrites an existing destination by default. ### Attack Path ...[truncated 1175 chars]- Remediation
View remediation
