From 714a5efc5d2994b81cc18775b40fff3d3473fa26 Mon Sep 17 00:00:00 2001 From: rookiestar28 Date: Sun, 1 Mar 2026 02:01:17 +0800 Subject: [PATCH] docs(security): align no-origin CSRF override guidance across README and deployment docs --- README.md | 26 +++++++++++ docs/deploy/lan.md | 4 ++ docs/deploy/local-only.md | 5 ++ docs/deploy/reverse-proxy.md | 45 +++++++++++++++++- docs/runtime_hardening_and_startup.md | 19 ++++++++ docs/security_checklist.md | 2 + docs/security_deployment_guide.md | 66 ++++++++++++++++++++------- 7 files changed, 148 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index cf17be6..a222ad6 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ This project is designed to make **ComfyUI a reliable automation target** with a - Explicit **Admin Token** boundary for write actions - Startup module capability gates (disabled modules do not register routes/workers) - Localhost-first defaults; remote access is opt-in +- Localhost no-origin CSRF override posture is explicitly surfaced at startup and in Security Doctor, with audit visibility for operator review - Strict outbound SSRF policy (callbacks + custom LLM base URLs) - Webhooks are **deny-by-default** until auth is configured - Encrypted webhook mode is **fail-closed** (invalid signature/decrypt/app-id checks are rejected) @@ -59,6 +60,30 @@ Deployment profiles and hardening checklists:
+Core runtime maintainability and contract hardening batch + +- Refactored startup/bootstrap responsibilities into clearer service slices to keep the entry path thin and easier to validate. +- Hardened provider adapter error contracts with safer HTTP error propagation and retry-after handling consistency. +- Replaced fragile JSON object extraction logic in LLM output parsing with stdlib decoder-based behavior for stronger edge-case resilience. +- Unified node/runtime consistency by converging shared image encoding helpers and internal node naming compatibility paths. +- Added and aligned regression coverage, then completed full verification gate pass (detect-secrets, pre-commit, backend unit suites, and frontend Playwright E2E). + +
+ +
+ +Security and reliability hotfix chain: startup gate cleanup, atomic audit writes, and clearer CSRF override posture + +- Cleaned up unreachable startup security-gate code after fatal raise paths, keeping fail-closed behavior explicit and reducing maintenance ambiguity. +- Hardened append-only audit integrity by making hash-chain write flow atomic under a process lock to avoid concurrent chain-fork risk. +- Added explicit startup warning when localhost no-origin override is enabled, plus a dedicated Security Doctor posture check/violation mapping for operator visibility. +- Added focused regression coverage for startup warning/doctor posture and audit lock path behavior. +- Completed full verification gate pass (detect-secrets, pre-commit, backend unit suites, and frontend Playwright E2E). + +
+ +
+ Standalone remote admin mobile console for phone/desktop operations - Added an independent remote admin entry page at `/openclaw/admin` (legacy `/moltbot/admin`), separate from the ComfyUI side panel. @@ -693,6 +718,7 @@ Notes: - `POST /openclaw/llm/chat` in localhost convenience mode (no admin token configured): - allows same-origin loopback requests - denies cross-origin requests with CSRF error + - if `OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=true`, requests missing `Origin` / `Sec-Fetch-Site` are allowed for local tooling compatibility; this posture is explicitly surfaced in startup logs, Security Doctor, and audit events - `/openclaw/llm/models` cache behavior: - key: `(provider, base_url)` - TTL: 5 minutes diff --git a/docs/deploy/lan.md b/docs/deploy/lan.md index 1fe8473..4ae12e0 100644 --- a/docs/deploy/lan.md +++ b/docs/deploy/lan.md @@ -41,6 +41,9 @@ OPENCLAW_ALLOW_REMOTE_ADMIN=1 # Require a token for Logs/Config viewing OPENCLAW_OBSERVABILITY_TOKEN=observability-secret +# Keep strict localhost no-origin behavior (do not relax on LAN) +OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0 + # Optional startup log hygiene (avoid stale historical error lines in UI) OPENCLAW_LOG_TRUNCATE_ON_START=1 ``` @@ -67,6 +70,7 @@ sudo ufw allow from 192.168.1.0/24 to any port 8188 - ❌ Do not forward port 8188 on your router. - ❌ Do not use `--listen 0.0.0.0` on a laptop connected to public WiFi. +- ❌ Do not set `OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=true` on LAN/shared deployments. ## Testing diff --git a/docs/deploy/local-only.md b/docs/deploy/local-only.md index a1b76f7..97256a1 100644 --- a/docs/deploy/local-only.md +++ b/docs/deploy/local-only.md @@ -40,6 +40,10 @@ No special configuration is required. - Keep SSRF relax flags disabled: - `OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=0` - `OPENCLAW_ALLOW_INSECURE_BASE_URL=0` +- **No-origin convenience override (optional, local-only)**: + - default/unset keeps strict no-origin denial + - set `OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=true` only when local CLI/tooling compatibility requires it + - keep it unset/disabled for normal browser-only local use - **Optional log hygiene**: - `OPENCLAW_LOG_TRUNCATE_ON_START=1` clears stale `openclaw.log` content once at startup. @@ -47,6 +51,7 @@ No special configuration is required. - ❌ Do not run with `--listen 0.0.0.0` or `--listen`. - ❌ Do not port-forward port 8188 on your router. +- ❌ Do not leave `OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=true` enabled longer than needed. ## Testing diff --git a/docs/deploy/reverse-proxy.md b/docs/deploy/reverse-proxy.md index b552965..cf6b952 100644 --- a/docs/deploy/reverse-proxy.md +++ b/docs/deploy/reverse-proxy.md @@ -3,12 +3,26 @@ For power users who want to run ComfyUI behind Caddy, Nginx, or Traefik. This adds limits, TLS, and header management. +## Shared-Boundary Warning + +OpenClaw and ComfyUI share the same upstream listener. +Blocking or authenticating `/openclaw/*` alone is not enough for public posture. +If your proxy forwards broad paths to ComfyUI, native ComfyUI routes may still be reachable. + +Treat reverse proxy policy as the primary boundary: + +- allow only the routes you intentionally need +- deny ComfyUI-native high-risk paths and their `/api/*` forms + ## Guidelines 1. **Block Sensitive Paths**: Prevent external access to admin/debug endpoints if not needed. - Block `/openclaw/logs/*` - Block `/openclaw/config` - Block `/openclaw/admin` and legacy `/moltbot/admin` when remote admin UI is not required + - Block ComfyUI-native high-risk paths: + - `/prompt`, `/history*`, `/view*`, `/upload*`, `/ws` + - `/api/prompt`, `/api/history*`, `/api/view*`, `/api/upload*`, `/api/ws` 2. **Timeouts**: ComfyUI generation can take time. Increase timeouts. - `proxy_read_timeout 600s;` (Nginx) 3. **Websockets**: ComfyUI requires WS support. @@ -26,8 +40,12 @@ comfyui.local { } # Security: Block sensitive OpenClaw paths from external access - @sensitive path /openclaw/logs* /openclaw/config /openclaw/admin /moltbot/admin - respond @sensitive 403 + @openclaw_sensitive path /openclaw/logs* /openclaw/config /openclaw/admin /moltbot/admin + respond @openclaw_sensitive 403 + + # Security: Block ComfyUI-native high-risk surfaces (direct + /api variants) + @comfy_native_sensitive path /prompt /history* /view* /upload* /ws /api/prompt /api/history* /api/view* /api/upload* /api/ws + respond @comfy_native_sensitive 403 } ``` @@ -61,15 +79,38 @@ server { location = /openclaw/admin { deny all; } + + # Block ComfyUI native high-risk routes (direct + /api variants) + location = /prompt { deny all; } + location /history { deny all; } + location /view { deny all; } + location /upload { deny all; } + location = /ws { deny all; } + + location = /api/prompt { deny all; } + location /api/history { deny all; } + location /api/view { deny all; } + location /api/upload { deny all; } + location = /api/ws { deny all; } } ``` +## Recommended Pattern: Allowlist-First Routing + +If you do not need full ComfyUI UI exposure, prefer explicit allowlist routing: + +- allow only required OpenClaw routes (for example `/openclaw/admin`, selected `/openclaw/*` APIs) +- deny everything else by default + +This reduces accidental exposure from ComfyUI route changes or API shim behavior differences. + ## If You Intentionally Expose Remote Admin Console Only do this on trusted/private access planes and keep backend protection enabled: - `OPENCLAW_ADMIN_TOKEN=` - `OPENCLAW_ALLOW_REMOTE_ADMIN=1` +- `OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0` (keep strict no-origin posture on shared/remote planes) - `OPENCLAW_LOG_TRUNCATE_ON_START=1` (optional, startup log hygiene) Use one more auth boundary at proxy layer (IP allowlist, SSO, or basic auth), for example: diff --git a/docs/runtime_hardening_and_startup.md b/docs/runtime_hardening_and_startup.md index 30ba14f..cc0f21e 100644 --- a/docs/runtime_hardening_and_startup.md +++ b/docs/runtime_hardening_and_startup.md @@ -40,6 +40,25 @@ Current mandatory checks: In `minimal` mode, the same checks emit warnings but do not block startup. +## Localhost no-origin override posture + +`OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN` controls a localhost convenience escape hatch for clients +that do not send `Origin` / `Sec-Fetch-Site` headers. + +- Default/unset: strict behavior remains active (no-origin requests are denied in convenience mode). +- When set to `true`: no-origin localhost requests are allowed in convenience mode. + +Operational visibility: + +- Startup emits an explicit warning when the override is enabled. +- Security Doctor reports this as an explicit posture check (`csrf_no_origin_override`, code `SEC-CSRF-001`). +- Startup audit includes a dedicated event so operators can trace when this override is active. + +Security note: + +- Keep this override disabled for shared/LAN/public deployments. +- Enable only for local CLI/tooling compatibility, and only as long as required. + ## Module startup boundaries Module enablement is decided during startup and then locked. diff --git a/docs/security_checklist.md b/docs/security_checklist.md index 4cf0b61..9e7572d 100644 --- a/docs/security_checklist.md +++ b/docs/security_checklist.md @@ -34,6 +34,8 @@ - [ ] Keep ComfyUI on localhost (`--listen 127.0.0.1`) unless LAN access required. - [ ] If exposing to LAN/Internet: set `OPENCLAW_ADMIN_TOKEN` environment variable. - [ ] Never expose admin endpoints without token. +- [ ] For shared/LAN/public exposure, keep `OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0` (or unset). +- [ ] Run `GET /openclaw/security/doctor` and verify no `csrf_no_origin_override` warning before exposure. ### 6. Debug Mode diff --git a/docs/security_deployment_guide.md b/docs/security_deployment_guide.md index b2dbef5..b49a374 100644 --- a/docs/security_deployment_guide.md +++ b/docs/security_deployment_guide.md @@ -24,6 +24,26 @@ Before using OpenClaw in any internet-facing setup, you must explicitly accept: 4. If you cannot satisfy the `public` profile baseline and checklist, do not deploy publicly. Use `local` or private/VPN-only access instead. 5. High-risk capabilities (external tools, registry sync, transforms, remote admin) must remain disabled unless there is a reviewed and time-bounded operational requirement. +## 0.1 Shared-Port Boundary Statement (Critical) + +OpenClaw runs inside ComfyUI and shares the same HTTP listener/port. + +This means: + +1. Protecting `/openclaw/*` endpoints does **not** automatically protect ComfyUI native endpoints. +2. If your public edge forwards raw ComfyUI upstream traffic broadly, attackers may still reach native ComfyUI surfaces. +3. Public deployment must enforce path-level allow/deny policy at reverse proxy (and network ACL), not just OpenClaw tokens. + +High-risk ComfyUI-native paths to explicitly deny on public edges (unless intentionally required): + +- direct paths: `/prompt`, `/history*`, `/view*`, `/upload*`, `/ws` +- API-shim paths: `/api/prompt`, `/api/history*`, `/api/view*`, `/api/upload*`, `/api/ws` + +Notes: + +- Exact ComfyUI route shape can vary by version and shim behavior. Use deny rules that cover both direct and `/api/*` forms. +- If you intentionally expose full ComfyUI UI to users, apply a separate hardened admin/user plane design and do not rely on OpenClaw route auth alone. + ## 1. Profile Matrix | Profile | Intended Use | Minimum Security Baseline | @@ -76,9 +96,12 @@ OPENCLAW_ENABLE_TRANSFORMS=0 OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=0 OPENCLAW_ALLOW_INSECURE_BASE_URL=0 OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDE=0 +OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0 # Optional but recommended OPENCLAW_ADMIN_TOKEN=change-this-local-admin-token +# Optional local CLI compatibility only (do not enable on LAN/public): +# OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=true # Optional startup log hygiene # OPENCLAW_LOG_TRUNCATE_ON_START=1 ``` @@ -89,9 +112,10 @@ OPENCLAW_ADMIN_TOKEN=change-this-local-admin-token 2. Keep remote admin disabled. 3. Keep external tools/registry sync/transforms disabled unless explicitly needed. 4. For local LLM providers (Ollama/LM Studio), use loopback URLs only (`localhost`/`127.0.0.1`/`::1`); keep `OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=0` and `OPENCLAW_ALLOW_INSECURE_BASE_URL=0`. -5. Run: +5. Keep `OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0` unless you explicitly need local CLI/no-origin compatibility. +6. Run: - `python scripts/check_deployment_profile.py --profile local` -6. If you enable optional high-risk features, document why and time-box the change. +7. If you enable optional high-risk features, document why and time-box the change. ## 4. LAN (Trusted Subnet) @@ -116,6 +140,7 @@ OPENCLAW_ENABLE_TRANSFORMS=0 OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=0 OPENCLAW_ALLOW_INSECURE_BASE_URL=0 OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDE=0 +OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0 # Optional startup log hygiene # OPENCLAW_LOG_TRUNCATE_ON_START=1 ``` @@ -125,11 +150,12 @@ OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDE=0 1. Restrict host firewall to trusted LAN subnets only. 2. Use distinct admin and observability tokens. 3. Keep bridge/tools/registry/transforms disabled unless there is a reviewed requirement. -4. Run: +4. Keep `OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0` for LAN deployments. +5. Run: - `python scripts/check_deployment_profile.py --profile lan` -5. Run the security diagnostics endpoint before production use: +6. Run the security diagnostics endpoint before production use: - `GET /openclaw/security/doctor` (admin boundary). -6. If using mobile/remote admin UI, expose `/openclaw/admin` only inside trusted LAN/VPN boundaries. +7. If using mobile/remote admin UI, expose `/openclaw/admin` only inside trusted LAN/VPN boundaries. ## 5. Public (Internet + Reverse Proxy) @@ -167,6 +193,7 @@ OPENCLAW_ENABLE_TRANSFORMS=0 OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=0 OPENCLAW_ALLOW_INSECURE_BASE_URL=0 OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDE=0 +OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0 # Optional startup log hygiene # OPENCLAW_LOG_TRUNCATE_ON_START=1 ``` @@ -175,16 +202,20 @@ OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDE=0 1. Never expose raw ComfyUI port directly to the internet. 2. Enforce authentication at reverse proxy and application layers. -3. Enforce split control plane in public posture (`OPENCLAW_CONTROL_PLANE_MODE=split` + external URL/TOKEN). -4. Keep risky features disabled on public user-facing plane. -5. Verify split posture from capabilities: +3. Enforce path-level boundary controls at reverse proxy: + - allow only required OpenClaw routes + - deny ComfyUI-native high-risk paths (`/prompt`, `/history*`, `/view*`, `/upload*`, `/ws`) and `/api/*` equivalents. +4. Enforce split control plane in public posture (`OPENCLAW_CONTROL_PLANE_MODE=split` + external URL/TOKEN). +5. Keep risky features disabled on public user-facing plane. +6. Keep `OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=0` in public deployments. +7. Verify split posture from capabilities: - `GET /openclaw/capabilities` and confirm `control_plane.mode=split` -6. Run: +8. Run: - `python scripts/check_deployment_profile.py --profile public` -7. Validate with project test and release gates before rollout: +9. Validate with project test and release gates before rollout: - `tests/TEST_SOP.md` - `RELEASE_CHECKLIST.md` -8. Ensure `/openclaw/admin` is blocked at public edge unless a separately hardened private admin plane is in place. +10. Ensure `/openclaw/admin` is blocked at public edge unless a separately hardened private admin plane is in place. ## 6. Bridge in Public Profile (only when absolutely required) @@ -209,12 +240,13 @@ The check fails if bridge is enabled without the mTLS/device-binding bundle. ## 7. Operational Red Lines 1. Do not use localhost convenience mode for shared/LAN/public deployments. -2. Do not enable `OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDE` in production. -3. Do not enable `OPENCLAW_SECURITY_DANGEROUS_PROFILE_OVERRIDE` in production. -4. Do not enable `OPENCLAW_SPLIT_COMPAT_OVERRIDE` in production. -5. Do not enable external tools/registry sync/transforms on public user-facing plane by default. -6. Do not use wildcard-like trust posture for callback destinations. -7. Do not treat this as a "set and forget" deployment; re-run profile checks after every config change. +2. Do not enable `OPENCLAW_LOCALHOST_ALLOW_NO_ORIGIN=true` in shared/LAN/public deployments. +3. Do not enable `OPENCLAW_SECURITY_DANGEROUS_BIND_OVERRIDE` in production. +4. Do not enable `OPENCLAW_SECURITY_DANGEROUS_PROFILE_OVERRIDE` in production. +5. Do not enable `OPENCLAW_SPLIT_COMPAT_OVERRIDE` in production. +6. Do not enable external tools/registry sync/transforms on public user-facing plane by default. +7. Do not use wildcard-like trust posture for callback destinations. +8. Do not treat this as a "set and forget" deployment; re-run profile checks after every config change. ## 8. Mechanical Gate Integration (Startup + CI)