OpenClaw github.com/openclaw/openclaw ↗
Node.js Gateway routing 20+ chat channels (WhatsApp/Telegram/Slack/Discord/Signal/iMessage/Matrix...) to LLM-backed agents. ClawHub skill marketplace. Single-trusted-operator threat model — tools run on the host by default; sandbox is opt-in. Config at ~/.openclaw/openclaw.json. Major advisory wave shipped Apr 22-24 2026 — eight High/Moderate GHSAs across Gateway config, OpenShell sandbox, MCP loopback owner spoofing, heredoc allowlist bypass, webhook rotation, Control-UI auth, and setup-api.js CWD hijack. Pin a build dated >= Apr 25 2026.
setup-api.js, model-driven Gateway-config mutation, OpenShell path traversal, MCP loopback owner spoofing, heredoc allowlist bypass, plus four more (webhook rotation, wildcard channel owners, Control UI bootstrap unauth, dotenv connector-host override). Upgrade to a patched build and rotate webhook secrets.Built-In Security Audit, Version Pinning, Node Baseline
OpenClaw ships a first-class security audit command that scans filesystem perms, gateway bind/auth, exec policy, plugin supply chain, and exposure flags. SECURITY.md now mandates Node.js >= 22.16.0 (citing CVE-2025-59466 async_hooks DoS and CVE-2026-21636 permission-model bypass). The Apr 2026 beta also introduced security.audit.suppressions for triaged audit findings.
node --version # require >= v22.16.0
openclaw security audit --deep --json
openclaw security audit --fix
npm i -g openclaw@<exact-version>
openclaw doctor && openclaw healthTip: run security audit --deep weekly via cron and after every openclaw update; commit the JSON output for diffing; use security.audit.suppressions sparingly with review dates so triaged findings don't silently rot.
Gateway / Control-UI Network Binding
The Gateway listens on http://127.0.0.1:18789/ by default. Keep gateway.bind: "loopback" and front remote access with Tailscale Serve (which keeps Gateway on loopback) rather than LAN/public binds.
{
gateway: {
mode: "local",
bind: "loopback",
controlUi: {
allowInsecureAuth: false,
dangerouslyDisableDeviceAuth: false
}
}
}Tip: never set gateway.bind to "lan" / "custom" without simultaneously setting gateway.auth.mode to token or password.
Authentication (Gateway Token / Password / Trusted Proxy)
Three auth modes for the Gateway WebSocket: token, password, trusted-proxy. No built-in OAuth or 2FA for the Gateway itself — 2FA is delegated to upstream channels. The standalone browser-control API only honors token/password, never proxy identity.
{ gateway: { auth: { mode: "token", token: "<64-char-random>" } } }
// or
export OPENCLAW_GATEWAY_PASSWORD="<long-random>"Tip: rotate gateway.auth.token (and provider keys in ~/.openclaw/agents/<id>/agent/auth-profiles.json) on a schedule; restart the Gateway after rotation.
Isolation (Sandbox Modes, Docker, Workspace Scope)
Sandbox defaults to off for the main session — tools execute on the host. Force isolation for non-main sessions and restrict workspace mounts. Backends: Docker (default), SSH, OpenShell.
{
agents: {
defaults: {
sandbox: { mode: "all", scope: "agent", workspaceAccess: "ro" }
}
},
tools: { exec: { applyPatch: { workspaceOnly: true } } }
}Tip: run the Docker sandbox with --read-only and dropped capabilities; never set tools.exec.applyPatch.workspaceOnly: false — the audit flags it as dangerous. OpenShell sandbox: GHSA-wppj-c6mr-83jj + GHSA-5h3g-6xhh-rg6p (Apr 23 2026, both High) patched path-traversal escapes via the filesystem bridge — pre-patch, the OpenShell backend allowed reads + writes outside the sandbox mount root. Pin a post-Apr-23 build.
Tool Allowlist / Permission System
Tools are grouped (group:automation, group:runtime, group:fs, plus named tools gateway, cron, sessions_spawn, sessions_send). Use the messaging profile and deny by default; require human approval on exec. GHSA-x3h8-jrgh-p8jx (Apr 23 2026) closed a heredoc / shell-expansion bypass in the execution allowlist analyser — pre-patch, attackers could smuggle disallowed commands past group:automation/runtime rules via unquoted heredocs.
{
tools: {
profile: "messaging",
deny: ["group:automation", "group:runtime", "group:fs",
"gateway", "cron", "sessions_spawn", "sessions_send"],
exec: { security: "deny", ask: "always" }
}
}Tip: the gateway tool can mutate config persistently — keep it denied for untrusted channels. GHSA-cwj3-vqpp-pmxr (Apr 24 2026) showed LLM-driven calls were able to mutate Gateway config until the model-driven config mutation guard landed — upgrade past Apr 24.
Credential / API Key Handling
Secrets live under ~/.openclaw/credentials/<channel>/, ~/.openclaw/agents/<id>/agent/auth-profiles.json (model keys), and optional ~/.openclaw/secrets.json. No built-in vault — file perms are the boundary.
chmod 700 ~/.openclaw
chmod 600 ~/.openclaw/openclaw.json ~/.openclaw/secrets.json
chmod -R go-rwx ~/.openclaw/credentials ~/.openclaw/agents
# prefer file-references over inline:
# channels.telegram.tokenFile: "/path/to/token"Tip: never commit openclaw.json; openclaw security audit checks fs.* perms — let --fix apply them.
Plugin / Skill / MCP Server Vetting
Skills are markdown directories (SKILL.md) installed from ClawHub (runs VirusTotal + ClawScan + static analysis). Plugins load in-process with operator privileges. MCP servers configured via openclaw mcp set. Treat all three as untrusted code.
openclaw skills install <slug>
openclaw plugins install <pkg>
openclaw plugins allow
openclaw mcp set <name> '<json>'
# avoid --dangerously-force-unsafe-installConfig knobs: skills.install.allowUploadedArchives: false, plugins.entries.acpx.config.permissionMode: "approve-each" (never approve-all). MCP stdio blocks NODE_OPTIONS / PYTHONSTARTUP / PERL5OPT automatically. GHSA-r6xh-pqhr-v4xh (Apr 23 2026) closed an MCP loopback owner-spoofing bug — owner context is now derived from the local pairing, not the server's bearer token.
Tip: pin skills via agents.list[].skills allowlist (non-empty allowlist is final, doesn't merge). Pinned skills get update-signing via the ATLAS v1.0 roadmap — opt into signed-only installs once available.
Prompt Injection Defense
SECURITY.md explicitly states prompt-injection without a boundary bypass is out of scope — defense is the operator's job. The primary lever is contextVisibility, which filters quoted/forwarded/thread context that LLMs ingest as instructions.
{
contextVisibility: "allowlist_quote",
session: { dmScope: "per-channel-peer" },
channels: {
whatsapp: { dmPolicy: "pairing",
groups: { "*": { requireMention: true } } }
},
browser: {
ssrfPolicy: { dangerouslyAllowPrivateNetwork: false,
hostnameAllowlist: ["*.example.com"] }
}
}Tip: combine context filtering with tools.exec.security: "deny" and ask: "always"; approve pairings deliberately via openclaw pairing approve <channel> <code>.
Updates, Patch Hygiene, Threat-Model Roadmap
Three release channels: stable, beta, dev. The openclaw update command auto-detects install type, runs diagnostics, restarts the Gateway. The upstream MITRE ATLAS v1.0 threat model (Feb 2026 rebase) plus a new formal verification doc are now part of the security baseline. Net-new 2026 controls in the roadmap: VirusTotal scanning of ClawHub skills, token encryption at rest, recommended skill sandboxing, signed skill packages, explicit "no rate limiting today" gap.
openclaw update --channel stable --dry-run
openclaw update --channel stable
openclaw doctor && openclaw health
# rollback:
npm i -g openclaw@<previous-version>The May 2026 beta (v2026.5.16-beta.5) added an HTTPS managed forward-proxy (proxy.tls.caFile), rejection of forged loopback Control-UI origins from non-local proxy paths, and a 15s timeout on legacy before_agent_start plugin hooks. Until skill update signing ships, compensate with a self-hosted reverse proxy that rate-limits the Gateway and encrypt ~/.openclaw/credentials/ at rest (FileVault on macOS, LUKS on Linux).
Tip: stay on stable; subscribe to GitHub Security Advisories on openclaw/openclaw; rerun security audit --deep after every update because config migrations can re-introduce defaults.
Logging / Monitoring / Telemetry
OpenClaw writes session transcripts to ~/.openclaw/agents/<agentId>/sessions/*.jsonl and Gateway logs to /tmp/openclaw/openclaw-YYYY-MM-DD.log — anyone with FS access can read them. Enable redaction; export metrics via Prometheus / OpenTelemetry. ClawHub telemetry is opt-out.
{
logging: {
redactSensitive: "tools",
redactPatterns: [/* tokens, internal hostnames */]
}
}export CLAWHUB_DISABLE_TELEMETRY=1
# scrape: gateway.prometheus + gateway.opentelemetry endpointsTip: logging.redactSensitive: "tools" is what audit --fix restores — don't disable it; rotate/encrypt ~/.openclaw/agents/*/sessions/ if the host is shared.