The webapi binds loopback by default (argus_skill/webapi/server.py, serve() at L712-714: host 127.0.0.1, port 8799), and the docs note that this default "needs no token" (docs/mobile.md ~L112). Two standard loopback-server guards are currently absent:
- No Host-header allowlist —
create_app installs no TrustedHostMiddleware or equivalent, so the server answers requests regardless of the Host header they carry.
- No Origin /
Sec-Fetch-Site validation — the CORS middleware (L631-641) only governs preflights and response headers; nothing checks the Origin or Sec-Fetch-Site of the requests themselves.
Loopback services without these checks are the classic target of DNS rebinding (a page served from a rebound hostname becomes same-origin to the port) and are reachable by any other local user on multi-user machines, since a loopback bind is machine-global. The desktop host already models the stronger posture — it always sets ARGUS_SKILL_WEB_TOKEN for the web UI it launches (desktop-tauri/src-tauri/src/backend.rs ~L920).
Suggested hardening:
- Reject requests whose
Host is not 127.0.0.1[:8799] / localhost[:8799].
- Require
Sec-Fetch-Site: same-origin (or a matching Origin) on non-GET requests.
- Optionally, mint a per-run random token for the tokenless loopback mode, as the desktop host already does — this also covers the multi-user-machine case.
The webapi binds loopback by default (
argus_skill/webapi/server.py,serve()at L712-714: host127.0.0.1, port 8799), and the docs note that this default "needs no token" (docs/mobile.md~L112). Two standard loopback-server guards are currently absent:create_appinstalls noTrustedHostMiddlewareor equivalent, so the server answers requests regardless of theHostheader they carry.Sec-Fetch-Sitevalidation — the CORS middleware (L631-641) only governs preflights and response headers; nothing checks theOriginorSec-Fetch-Siteof the requests themselves.Loopback services without these checks are the classic target of DNS rebinding (a page served from a rebound hostname becomes same-origin to the port) and are reachable by any other local user on multi-user machines, since a loopback bind is machine-global. The desktop host already models the stronger posture — it always sets
ARGUS_SKILL_WEB_TOKENfor the web UI it launches (desktop-tauri/src-tauri/src/backend.rs~L920).Suggested hardening:
Hostis not127.0.0.1[:8799]/localhost[:8799].Sec-Fetch-Site: same-origin(or a matchingOrigin) on non-GET requests.