T09 · Insecure Skill Coding Practices
- Location
src/storage.js:25- Finding
Path Traversal Through Unsanitized User Identifier
- Content
View full analysis
arg.startsWith('--user=')); if (userArg) { return userArg.split('=')[1]; } return process.env.MINER_USER || 'default'; } ``` ```js // src/storage.js:25-26 function getDataFilePath(userId) { return path.join(DATA_DIR, `${userId || 'default'}.json`); } ``` ```js // src/storage.js:37-48 function loadUserData(userId) { initDataDir(); const filePath = getDataFilePath(userId); if (!fs.existsSync(filePath)) { return { sessions: [], tags: [] }; } try { const content = fs.readFileSync(filePath, 'utf-8'); return JSON.parse(content); ``` ```js // src/storage.js:58-69 function saveUserData(userId, data) { initDataDir(); const filePath = getDataFilePath(userId); try { fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8'); } catch (error) { console.error('保存数据失败:', error.message); } } ``` ### Technical Analysis The CLI accepts a user identifier from `--user=` or the `MINER_USER` environment variable and returns it without validation. The storage module interpolates this value into a filename and passes it to `path.join`. `path.join` normalizes traversal components but does not guarantee that the resulting path remains under `DATA_DIR`. A value containing components such as `../../` can therefore resolve outside the intended conversation-data directory. The resulting path reaches both a filesystem read sink (`fs.readFileSync`) and a write sink (`fs.writeFileSync`). Reads are directly reachable through CLI commands that load user data. The write sink is exposed through the storage module API and can be reached by a ...[truncated 2028 chars]- Remediation
View remediation
