Primary finding
POST /api/settings allows unauthenticated rewrite of API keys, Neo4j credentials and webhook URLs
- backend/app/api/settings.py:168-257
- backend/app/api/settings.py:220-224
- backend/app/__init__.py:47-49
There is no authentication or authorization in front of /api/settings. CORS is open to any origin (`*`). An attacker who knows or guesses the deployment URL can POST {neo4j: {password: 'x'}, llm: {api_key: 'attacker-key'}} and silently exfiltrate / redirect future LLM and webhook traffic, or rewrite Config.WEBHOOK_URL to attacker-controlled host so future simulation completion webhooks leak to them. This is editable at runtime so it persists for the process lifetime. The comment in webhook_service notes the URL itself never leaves the backend, but the *attacker* can write it. There is no CSRF token, no IP allowlist, no admin guard.
Recommendation
Gate /api/settings behind authentication (env-var admin token, localhost-only bind, or session auth). At minimum require a header like X-Admin-Token compared against Config.ADMIN_TOKEN and refuse the route when no token is set in a non-DEBUG deployment. Tighten CORS to specific origins for these admin routes.