T09 · Insecure Skill Coding Practices
- Location
server.js:18- Finding
Unauthenticated Network-Accessible AI and File Management APIs
- Content
View full analysis
{ ``` ```js app.post('/api/save', async (req, res) => { ``` ```js app.get('/api/files', async (req, res) => { ``` ```js app.delete('/api/files/:project/:filename', async (req, res) => { ``` ```js app.delete('/api/projects/:project', async (req, res) => { ``` The server is started without restricting it to the loopback interface: ```js app.listen(PORT, () => console.log(`🚀 Server running on http://localhost:${PORT}`)); ``` ### Technical Analysis The application does not authenticate callers or perform user/resource-level authorization on any API. This affects operations that: - Invoke the Gemini API using the server owner's API key. - Save attacker-controlled content to the server. - Enumerate saved projects and filenames. - Retrieve saved files through the public `/downloads` static route. - Delete individual files or entire project directories. Calling `app.listen(PORT)` without a hostname normally binds the service to all available interfaces, not only `localhost`. Consequently, the log message and documentation do not enforce the claimed local-only deployment model. The unrestricted `cors()` middleware permits arbitrary web origins to read responses and invoke supported cross-origin methods. This substantially increases exposure when the service is reachable from a victim's browser, local network, dev ...[truncated 2505 chars]- Remediation
View remediation
{ console.log(`Server running on http://${HOST}:${PORT}`); }); ``` 2. **Add authentication** - Require an authenticated session or bearer token for every `/api/*` route. - Do not treat network location or CORS as an authentication mechanism. - Store authentication secrets outside source control and compare tokens using timing-safe logic where applicable. 3. **Add authorization** - Associate projects with authenticated identities. - Verify ownership before listing, reading, saving, or deleting files. - Avoid exposing the complete downloads directory through unauthenticated static middleware. - Replace the static route with an authorized download controller. 4. **Restrict CORS** ```js app.use(cors({ origin: ['http://127.0.0.1:3000', 'http://localhost:3000'], methods: ['GET', 'POST', 'DELETE'], credentials: true })); ``` Omit CORS entirely if the frontend is always served from the same origin. 5. **Add abuse controls** - Rate-limit generation, save, list, download, and delete endpoints. - Apply stricter per-route body limits. - Limit the number and decoded size of files per request. - Reject malformed or oversized base64 content before processing it. - Introduce Gemini request quotas per authenticated user. 6. **Protect destructive operations** - Require authorization and CSRF protection when cookie-based sessions are used. - Consider soft deletion, audit logging, or recovery retention for projects. - Return appropriate errors without disclosing unnecessary implementation details. 7. **Harden path containment checks** - Use `path.resolve()` and compare against a downloads-root path ending with the platform separator. - Continue applying strict project and filename validation. - Prevent symbol ...[truncated 84 chars]
