Skip to content

fix(webapi): require loopback Host, JSON Content-Type, and a body cap - #11

Merged
Upper9527 merged 1 commit into
AMAP-ML:mainfrom
SashaMIT:fix/dashboard-host-and-csrf
Aug 17, 2026
Merged

fix(webapi): require loopback Host, JSON Content-Type, and a body cap#11
Upper9527 merged 1 commit into
AMAP-ML:mainfrom
SashaMIT:fix/dashboard-host-and-csrf

Conversation

@SashaMIT

@SashaMIT SashaMIT commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • The FastAPI workbench is an unauthenticated loopback control plane: any caller that can reach the port can inject instructions, resolve approvals, or create/stop runs.
  • Host allowlist (loopback bind only): reject requests whose Host header is not loopback (or the configured bind host). A DNS-rebinding page that reaches the TCP port with Host: evil.example can no longer read /api/meta or drive the agent.
  • JSON Content-Type on mutating /api routes: require application/json (optional charset). Simple cross-origin text/plain or form posts are 415.
  • Body cap before JSON parse: reject control bodies over 1 MiB with 413.
  • Non-loopback bind still requires a bearer token. Host allowlist does not apply there.

Test plan

  • pytest tests/webapi/test_hardening.py tests/webapi/test_webapi.py tests/supervisor/test_supervisor.py (56 passed, 1 skipped)
  • DNS-rebinding Host values return 403
  • text/plain / form POSTs to /api/runs/{id}/instructions return 415
  • Oversized body returns 413
  • Bearer token still required; Host: evil.example is 403 even with a valid token on loopback
  • bind_host=0.0.0.0 with a token still accepts a LAN Host

@Upper9527 Upper9527 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. validating the incoming Host header for loopback-only deployments;
  2. requiring application/json on state-changing control endpoints;
  3. applying an explicit request-body size limit before JSON parsing;
  4. 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>
@SashaMIT
SashaMIT force-pushed the fix/dashboard-host-and-csrf branch from f560a78 to af7d2d9 Compare August 17, 2026 08:05
@SashaMIT

Copy link
Copy Markdown
Contributor Author

Thanks. Rebased onto current main and reimplemented this against the FastAPI server in src/lh_harness/webapi/server.py.

Loopback deployments now reject a non-loopback Host (including DNS-rebinding style values). State-changing /api POSTs require application/json (charset allowed) and a 1 MiB body cap before JSON parse. Bearer-token and non-loopback bind behavior is unchanged: the Host allowlist is loopback-only, and a token is still required off-loopback.

Tests cover the Host cases, simple cross-origin content types, oversized bodies, and the existing token / 0.0.0.0 path.

@SashaMIT SashaMIT changed the title fix(dashboard): require loopback Host and JSON Content-Type on control plane fix(webapi): require loopback Host, JSON Content-Type, and a body cap Aug 17, 2026
@Upper9527
Upper9527 merged commit 0074d57 into AMAP-ML:main Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants