T09 · Insecure Skill Coding Practices
- Location
lib/store.js:323- Finding
Path Traversal Through Entity Names Allows Writes Outside the Entity Directory
- Content
View full analysis
`- **${k}:** ${v}`).join('\n'); const md = [ `# ${entity.name}`, `**Type:** ${entity.entityType}`, `**First seen:** ${entity.firstSeen.slice(0, 10)}`, `**Last updated:** ${entity.lastUpdated.slice(0, 10)}`, '', attrs || '_(no attributes)_', ].join('\n'); try { const dirPath = path.join(this.memoryDir, dir); this._ensureDir(dirPath); fs.writeFileSync(path.join(dirPath, filename), md); } catch {} } ``` SQLite backend: ```js _writeEntityMd(entity) { const dir = entity.entityType === 'person' ? 'people' : 'decisions'; const dirPath = path.join(this.memoryDir, dir); this._ensureDir(dirPath); const filename = `${entity.name.toLowerCase().replace(/\s+/g, '-')}.md`; const attrs = Object.entries(entity.attributes).map(([k, v]) => `- **${k}:** ${v}`).join('\n'); const md = `# ${entity.name}\n**Type:** ${entity.entityType}\n**First seen:** ${entity.firstSeen.slice(0, 10)}\n**Last updated:** ${entity.lastUpdated.slice(0, 10)}\n\n${attrs || '_(no attributes)_'}\n`; try { fs.writeFileSync(path.join(dirPath, filename), md); } catch {} } ``` CLI entry point: ```js case 'entity': { const name = args[1]; const type = args[2]; if (!name || !type) return usage('entity [--attr key=value ...]'); const attrs = {}; for (let i = 3; i < args.length; i++) { if (args[i] === '--attr' && args[i + 1]) { const [k, ...v] = args[i + 1].split('='); if (k) attrs[k] ...[truncated 2131 chars]- Remediation
View remediation
