T05 · Unauthorized Access and Privilege Escalation
- Location
index.js:119- Finding
Recursive workspace scanning follows symbolic links outside the authorized scan root
- Content
View full analysis
filePath.includes(ignored))) continue; if (fs.existsSync(filePath)) { const stat = fs.statSync(filePath); if (stat.isDirectory()) { getAllFiles(filePath, fileList); ``` `scan.js:45-65`: ```javascript function recursiveScan(dir) { let results = []; const files = fs.readdirSync(dir); for (const file of files) { const fullPath = path.join(dir, file); // Skip ignored directories if (['node_modules', '.git', 'media', 'dist', 'coverage', '.openclaw', 'memory', 'cache', 'ai-game-engine', 'repo'].includes(file)) continue; // Skip self, env files, and lock files if (file === 'index.js' || file === 'scan.js' || file.endsWith('.env')) continue; if (['package-lock.json', 'pnpm-lock.yaml', 'yarn.lock'].includes(file)) continue; if (file.endsWith('.tmLanguage.json')) continue; try { const stats = fs.statSync(fullPath); if (stats.isDirectory()) { results = results.concat(recursiveScan(fullPath)); } else if (stats.isFile() && stats.size < 500 * 1024) { ``` ### Technical Analysis Both recursive scanners use `fs.statSync()`, which follows symbolic links. Neither implementation first uses `fs.lstatSync()` to reject links, resolves the canonical path with `fs.realpathSync()`, nor verifies that the resolved target remains under the canonical workspace root. Consequently, a symbolic link placed inside the workspace ...[truncated 2107 chars]- Remediation
View remediation
