T09 · Insecure Skill Coding Practices
- Location
SKILL.md:190- Finding
Persistent Unauthenticated API Exposure of Sensitive Operational Data
- Content
View full analysis
{ const data = JSON.parse(fs.readFileSync('./cron-jobs.json', 'utf8')); res.json(data); }); // Agent intel (CRUD) app.get('/api/agent-intel', (req, res) => { /* ... */ }); app.post('/api/agents/intel', (req, res) => { /* ... */ }); // Security audit (read from file, updated by daily cron) app.get('/api/security-audit', (req, res) => { const data = JSON.parse(fs.readFileSync('./security-audit/audit-data.json', 'utf8')); res.json(data); }); // Architecture app.get('/api/architecture', (req, res) => { /* ... */ }); // Backlog app.get('/api/backlog', (req, res) => { const data = JSON.parse(fs.readFileSync('./backlog.json', 'utf8')); res.json(data); }); app.listen(8005, () => console.log('Ops Deck API on :8005')); ``` ```bash pm2 start ecosystem.config.cjs pm2 save pm2 startup # auto-start on boot ``` The documented dashboard also exposes cron payload and delivery details: ```text Visual calendar of all scheduled agent tasks. See what runs when, last status, next run, error streaks. Click to view payload and delivery config. ``` ### Technical Analysis The example API does not implement authentication or authorization. Calling `app.listen(8005)` without specifying a host normally causes Node.js to listen on an unspecified address, potentially making the API reachable through non-loopback interfaces. The global `cors()` middleware permits cross-origin browser access without restricting origins. The affected endpoints expose information about scheduled jobs, security controls, infrastructure architecture, agent intelligence, ...[truncated 2282 chars]- Remediation
View remediation
{ console.log('Ops Deck API on http://127.0.0.1:8005'); }); ``` 2. Require authentication for every endpoint and enforce authorization separately for read and write operations. 3. Restrict CORS to the exact trusted dashboard origin rather than calling unrestricted `cors()`: ```javascript app.use(cors({ origin: 'http://127.0.0.1:5173', methods: ['GET', 'POST'], credentials: true })); ``` 4. Do not expose raw cron payloads, delivery configuration, agent configuration, or secrets. Add schema-based allowlists and redact tokens, credentials, internal addresses, and command arguments. 5. Apply CSRF protection to state-changing endpoints when cookie-based authentication is used. 6. Add rate limiting, request-size limits, security headers, structured access logging, and robust error handling. 7. Make PM2 startup an explicit opt-in production step after the user has configured authentication, host binding, and firewall controls. 8. Document how to disable and remove persistence, including the relevant `pm2 unstartup`, `pm2 delete`, and `pm2 save` workflow. 9. If remote access is required, place the API behind an authenticated TLS reverse proxy and firewall port 8005 from direct external access. ]]>
