T05 · Unauthorized Access and Privilege Escalation
- Location
index.js:104- Finding
Unauthenticated Network-Accessible HTTP API Exposes and Mutates Agent Data
- Content
View full analysis
{ res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Content-Type', 'application/json'); const sendError = (msg) => { res.end(JSON.stringify({ error: msg })); }; const sendSuccess = (data) => { res.end(JSON.stringify(data)); }; ``` Representative sensitive read operation: ```javascript else if (req.url.startsWith('/api/messages') && req.method === 'GET') { const urlObj = require('url').parse(req.url, true); const peerId = urlObj.query.peer; const messages = this.db.all(` SELECT * FROM messages WHERE (from_agent = ? AND to_agent = ?) OR (from_agent = ? AND to_agent = ?) ORDER BY created_at ASC `, [this.nodeId, peerId, peerId, this.nodeId]); sendSuccess(messages); } ``` Representative state-changing operations: ```javascript else if (req.url === '/api/send' && req.method === 'POST') { let body = ''; req.on('data', chunk => body += chunk); req.on('end', async () => { const { to, message } = JSON.parse(body); await this.core.sendMessage(to, message); sendSuccess({ success: true }); }); } else if (req.url === '/api/publish' && req.method === 'POST') { let body = ''; req.on('data', chunk => body += chunk); req.on('end', async () => { const { skillPath, price, metadata } = JSON.parse(body); const skillId = await this.skills.publish(skillPath, price, metadata); await this.core.shareSkill( skillId, metadata.name || skillPath, metadata.description, price ); sendSuccess({ success: true, skillId }); }); } ``` The server is started without restricting it to the loopback interface: ```javascript this.httpServer.listen(thi ...[truncated 2622 chars]- Remediation
View remediation
