Unauthenticated remote uninstall in my own EDR agent, and the four other auth bugs that turned out to be the same bug
Sentora is my own project, so this is a postmortem on my own code, not someone else’s. The agent shipped this: @/app.post(“/self_destruct”) async def self_destruct(request: Request): threading.Thread(target=perform_destruction, daemon=True).start() return sanic_json({“status”: “Destruction initiated”}) No auth. Listening on 0.0.0.0:9099. perform_destruction() ran rm -rf “$(pwd)”. One unauthenticated POST from anywhere on the subnet uninstalled the EDR. The four others: Permissive auth on by default. A _is_permissive_auth() helper accepted any non-empty X-Agent-Key when a specific env var was unset. Nothing in the installer, the systemd unit, or the scheduled task ever set that var, so every default install accepted X-Agent-Key: a on /soar/execute, which runs commands. Unauthenticated automation reporting. The server took a task_id from the request body and wrote a status. Enumerate the IDs, POST status: SUCCESS, and every queued containment action flips to done. The real agent stops seeing it as pending, so the isolation never runs, and the dashboard goes green. Not a bypass so much as a way to make the SOC watch a screen that says everything worked. LDAP injection in login. search_filter = login_filter % username, with only a length check on the input. Missing authorization on 8 routes. 143 routes, 103 with a decorator. Authentication was solid (opaque tokens, SHA-256 at rest, expiry enforced in SQL), which is exactly why I stopped looking at authorization. Any logged-in account could hit run_playbook, delete_soar_action, and test_ldap_connection, the last of which works as a credential oracle against the directory. All five reduce to the same thing: I was taking the caller’s word for who they were. Identity from the URL path, from a metadata.agent body field, from a header being non-empty, from X-Forwarded-For, and from being authenticated at all. I only caught the route bugs by writing a test that walks the AST and asserts every route is either explicitly public or carries a check. It failed on the first run and named all eight. Reading code to spot a missing decorator does not work, because nothing is on the page to notice. Full writeup with the fixes: https://d3vhex.github.io/2026-08-25-unauthenticated-remote-uninstall/ Repo (AGPL): https://github.com/d3vhex/Sentora Everything above is fixed on main. The agent listener is still the most interesting surface if anyone wants to poke at it, and I would rather hear about it here than in an incident. submitted by /u/RevolutionaryPie4948 [link] [comments]Technical Information Security Content & DiscussionRead More