RagLeap
Blog

A security incident, and what we did about it

We believe in documenting real problems, not hiding them. While checking authentication in core/api.py before starting a new feature, we found a real gap — and decided the honest thing to do was fix it properly and write up exactly what happened.

What was found

  • core/api.py had zero authentication on any route, including the endpoint that flips autonomy to full mode.
  • Docker was publishing 6 ports on 0.0.0.0 — the API, Postgres, Redis, Neo4j, and voice — invisible to ufw status because Docker's own iptables rules route around ufw entirely.
  • All three channel routers (Telegram/WhatsApp/Discord) accepted a YES/NO approval reply from any sender, not just the configured owner.
  • A Postgres superuser was running with a default password, also present in the public GitHub repo's compose file.

What we checked before assuming the worst

We ran real forensics — Postgres pg_stat_activity, roles and extensions, Redis key names and command stats, container process checks, and 7 days of access logs on the exposed API port. No sign of actual compromise was found. Traffic was scanner noise only — zero hits on the sensitive endpoints.

What we fixed

  • All service ports now bind to 127.0.0.1 by default in docker-compose.yml.
  • Approval replies are now checked against the exact configured owner, with a constant-time comparison — a stranger's YES or NO now changes nothing.
  • WhatsApp and Telegram webhooks fail closed without a valid signature.
  • An optional RAGLEAP_API_KEY global auth middleware, off by default, on by your choice.

This is the standard we hold ourselves to: document the real gap, fix it properly, and say so publicly rather than quietly patching and moving on.

Back to the blog