Summary
When OpenClaw's gateway is behind a reverse proxy (Nginx, Caddy, HAProxy, Traefik), the default 127.0.0.1 bind address creates a false sense of security. The gateway trusts all connections from localhost, but the reverse proxy forwards external traffic to 127.0.0.1 — effectively granting unauthenticated admin access to anyone on the internet.
This is documented in the forensic analysis as the primary architectural flaw exploited in the O'Reilly internet scan that discovered hundreds of exposed instances.
Attack Flow
┌──────────────┐ HTTPS ┌──────────────┐ 127.0.0.1 ┌──────────────┐
│ Attacker │ ──────────────▶│ Nginx/Caddy │ ──────────────▶│ OpenClaw │
│ (internet) │ │ (port 443) │ :18789 │ Gateway │
└──────────────┘ └──────────────┘ └──────────────┘
│
Gateway sees source
IP = 127.0.0.1
│
┌────────▼────────┐
│ AUTH BYPASSED! │
│ Full admin │
│ access granted │
└─────────────────┘
Current Gap
scan_network.sh CHK-NET-007 detects when a reverse proxy is running but trustedProxies is not configured. However, it does not check the critical combination:
- Gateway bound to
127.0.0.1 (appears safe)
- Reverse proxy detected (Nginx/Caddy on port 80/443)
- Gateway
requireAuth is disabled or token is missing — Not checked together
- Reverse proxy config does not set
X-Forwarded-For or auth headers — Not checked
The existing CHK-NET-007 emits an info severity finding. This should be a critical finding when combined with missing auth.
Proposed Check: CHK-CFG-013
Location: scripts/scan_config.sh (config-level check) with cross-reference to network state
Logic:
IF reverse_proxy_detected
AND gateway.requireAuth != true
AND gateway.auth.token is empty
THEN -> CRITICAL: "Reverse proxy auth bypass -- gateway trusts localhost but proxy forwards external traffic"
Additionally scan for:
- Nginx configs that proxy_pass to the gateway port without
proxy_set_header X-Real-IP
- Caddy configs that reverse_proxy to gateway without
trusted_proxies
Evidence to include:
{
"id": "CHK-CFG-013",
"severity": "critical",
"title": "Reverse proxy auth bypass detected",
"description": "A reverse proxy (nginx) is forwarding external traffic to the gateway on 127.0.0.1:18789, but gateway authentication is disabled. All external users receive full admin access.",
"evidence": "proxy=nginx:443 -> gateway=127.0.0.1:18789, requireAuth=false, auth.token=<not set>",
"remediation": "Set gateway.requireAuth=true and configure a strong gateway.auth.token in openclaw.json. Also configure trustedProxies to the proxy's IP address.",
"auto_fix": "jq '.gateway.requireAuth = true' config.json > config.json.tmp && mv config.json.tmp config.json"
}
Nginx/Caddy Config Scanning (Optional Deep Scan)
When --deep flag is passed, also scan common reverse proxy config locations:
# Nginx
/etc/nginx/sites-enabled/*
/etc/nginx/conf.d/*
# Caddy
/etc/caddy/Caddyfile
$HOME/.config/caddy/Caddyfile
# HAProxy
/etc/haproxy/haproxy.cfg
Look for patterns like:
# VULNERABLE -- no auth header forwarded
location / {
proxy_pass http://127.0.0.1:18789;
}
# SAFE -- forwards real client IP
location / {
proxy_pass http://127.0.0.1:18789;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
References
- Forensic analysis: "The Gateway and Protocol Multiplexing" section
- O'Reilly internet scan: hundreds of exposed instances via Shodan
- OWASP ASI02: Tool Misuse
- Related checks: CHK-CFG-006, CHK-CFG-007, CHK-NET-007
Summary
When OpenClaw's gateway is behind a reverse proxy (Nginx, Caddy, HAProxy, Traefik), the default
127.0.0.1bind address creates a false sense of security. The gateway trusts all connections from localhost, but the reverse proxy forwards external traffic to127.0.0.1— effectively granting unauthenticated admin access to anyone on the internet.This is documented in the forensic analysis as the primary architectural flaw exploited in the O'Reilly internet scan that discovered hundreds of exposed instances.
Attack Flow
Current Gap
scan_network.shCHK-NET-007 detects when a reverse proxy is running buttrustedProxiesis not configured. However, it does not check the critical combination:127.0.0.1(appears safe)requireAuthis disabled or token is missing — Not checked togetherX-Forwarded-Foror auth headers — Not checkedThe existing CHK-NET-007 emits an
infoseverity finding. This should be a critical finding when combined with missing auth.Proposed Check: CHK-CFG-013
Location:
scripts/scan_config.sh(config-level check) with cross-reference to network stateLogic:
Additionally scan for:
proxy_set_header X-Real-IPtrusted_proxiesEvidence to include:
{ "id": "CHK-CFG-013", "severity": "critical", "title": "Reverse proxy auth bypass detected", "description": "A reverse proxy (nginx) is forwarding external traffic to the gateway on 127.0.0.1:18789, but gateway authentication is disabled. All external users receive full admin access.", "evidence": "proxy=nginx:443 -> gateway=127.0.0.1:18789, requireAuth=false, auth.token=<not set>", "remediation": "Set gateway.requireAuth=true and configure a strong gateway.auth.token in openclaw.json. Also configure trustedProxies to the proxy's IP address.", "auto_fix": "jq '.gateway.requireAuth = true' config.json > config.json.tmp && mv config.json.tmp config.json" }Nginx/Caddy Config Scanning (Optional Deep Scan)
When
--deepflag is passed, also scan common reverse proxy config locations:Look for patterns like:
References