fix(webapi): require loopback Host, JSON Content-Type, and a body cap - #11
Conversation
Upper9527
left a comment
There was a problem hiding this comment.
The security goal is still worthwhile, but this implementation targets the removed legacy dashboard server. Current main serves the dashboard through FastAPI in src/lh_harness/webapi/server.py, so this branch cannot be merged as-is.
Please rebase onto the latest main and reimplement the hardening against the current web API. Keep the replacement focused on:
- validating the incoming Host header for loopback-only deployments;
- requiring application/json on state-changing control endpoints;
- applying an explicit request-body size limit before JSON parsing;
- tests covering DNS-rebinding-style Host values, simple cross-origin content types, oversized bodies, and the existing bearer-token/non-loopback behavior.
A replacement PR is fine if rewriting this branch is inconvenient. Once the current FastAPI implementation and regression tests are ready, we can review it for merge.
The FastAPI control plane is unauthenticated on loopback. Reject DNS-rebinding Host values, require application/json on mutating /api routes, and bound the request body before JSON parse. Signed-off-by: Sasha Mitchell <sash.t.mitchell@gmail.com>
f560a78 to
af7d2d9
Compare
|
Thanks. Rebased onto current main and reimplemented this against the FastAPI server in Loopback deployments now reject a non-loopback Tests cover the Host cases, simple cross-origin content types, oversized bodies, and the existing token / |
Summary
Hostheader is not loopback (or the configured bind host). A DNS-rebinding page that reaches the TCP port withHost: evil.examplecan no longer read/api/metaor drive the agent./apiroutes: requireapplication/json(optional charset). Simple cross-origintext/plainor form posts are 415.Test plan
pytest tests/webapi/test_hardening.py tests/webapi/test_webapi.py tests/supervisor/test_supervisor.py(56 passed, 1 skipped)text/plain/ form POSTs to/api/runs/{id}/instructionsreturn 415Host: evil.exampleis 403 even with a valid token on loopbackbind_host=0.0.0.0with a token still accepts a LAN Host