19 KiB
name, description, author, homepage, metadata
| name | description | author | homepage | metadata | ||||
|---|---|---|---|---|---|---|---|---|
| dont-hack-me | 別駭我!基本安全檢測 — Security self-check for OpenClaw (Clawdbot/Moltbot). 14-point audit of your clawdbot.json: exposed gateway, missing auth, open DM policy, weak tokens, file permissions, reverse proxy bypass, Tailscale exposure, directory perms, browser control, log redaction, control UI exposure, mDNS broadcasting. Auto-fix included. Invoke: "run a security check" or "幫我做安全檢查". | 小安 Ann Agent — Taiwan 台灣 | https://github.com/peterann/dont-hack-me |
|
dont-hack-me
Security self-check skill for OpenClaw (formerly Clawdbot / Moltbot).
Reads ~/.clawdbot/clawdbot.json and checks 14 items that cover the most
common misconfigurations. Outputs a simple PASS / FAIL / WARN report.
How to run
Say any of:
- "run a security check"
- "check my security settings"
- "audit my clawdbot config"
- "audit my openclaw config"
- "am I secure?"
Checklist — step by step
When this skill is triggered, follow these steps exactly:
Step 0 — Read the config
Use the read tool to open ~/.clawdbot/clawdbot.json.
(Note: the config path is still ~/.clawdbot/ even after the OpenClaw rebrand.)
Parse the JSON content. If the file does not exist or is unreadable,
report an error and stop.
Also run shell commands to get file and directory permissions, and check the mDNS environment variable:
stat -f '%Lp' ~/.clawdbot/clawdbot.json
stat -f '%Lp' ~/.clawdbot/
echo ${CLAWDBOT_DISABLE_BONJOUR:-unset}
(On Linux: use stat -c '%a' instead of stat -f '%Lp')
Step 1 — Gateway Bind
- Path:
gateway.bind - Expected:
"loopback" - Valid values (schema-enforced):
"auto","lan","loopback","custom","tailnet" - PASS if the value is
"loopback"or the key is absent (default is"loopback") - FAIL if the value is
"lan","auto","custom","tailnet", or any non-loopback setting - Severity: CRITICAL — a non-loopback bind exposes your agent to the network
Step 2 — Gateway Auth Mode
- Path:
gateway.auth.mode - Expected:
"token"or"password" - Valid values (schema-enforced):
"token","password". At runtime,"none"is derived when neither token nor password is configured — but"none"and"off"cannot appear in the JSON file. - PASS if
gateway.auth.modeis"token"or"password" - PASS if
gateway.auth.modeis absent butgateway.auth.tokenexists (runtime resolves to"token") - WARN if the entire
gateway.authsection is absent, or bothmodeandtokenare absent — runtime may default to no authentication (unless the env varCLAWDBOT_GATEWAY_TOKENis set, which we cannot check from config alone) - Severity: CRITICAL — without auth anyone who can reach the gateway can control your agent
Step 3 — Token Strength
- Path:
gateway.auth.token - Expected: 32 or more characters
- PASS if the token is >= 32 characters
- WARN if the token is 16–31 characters
- FAIL if the token is < 16 characters or empty
- SKIP if auth mode is
"password"(passwords are user-chosen, don't judge length) - Severity: HIGH — short tokens are vulnerable to brute-force
Step 4 — DM Policy (per channel)
- Path:
channels.<name>.dmPolicyfor each channel - Expected:
"pairing","allowlist", or"disabled" - PASS if
dmPolicyis"pairing","allowlist", or"disabled" - PASS if
dmPolicyis"open"butallowFrom(same level) has at least one entry - FAIL if
dmPolicyis"open"andallowFromis missing or empty - SKIP if no channels are configured
- Severity: HIGH — an open DM policy lets anyone send commands to your agent
Step 5 — Group Policy (per channel)
- Path:
channels.<name>.groupPolicyfor each channel - Expected:
"allowlist"or"disabled" - Valid values (schema-enforced):
"open","disabled","allowlist" - PASS if
groupPolicyis"allowlist","disabled", or absent (default is"allowlist") - FAIL if
groupPolicyis"open" - SKIP if no channels are configured
- Severity: HIGH — an open group policy lets any group trigger your agent
Step 6 — File Permissions
- Check: file mode of
~/.clawdbot/clawdbot.json - Expected:
600or400(owner read/write only) - PASS if permissions are
600or400 - WARN if group or others can read but NOT write (e.g.,
644,640,604) — use bitwise check:(mode & 0o044) != 0and(mode & 0o022) == 0 - FAIL if others or group can write (e.g.,
777,666,662) — use bitwise check:(mode & 0o022) != 0 - Severity: MEDIUM — loose permissions let other users on the system read your tokens
Step 7 — Plaintext Secrets Scan
- Check: scan all string values in the JSON for keys named
password,secret,apiKey,api_key,privateKey,private_key(case-insensitive) that contain a non-empty string value - PASS if no such keys are found
- WARN if such keys exist — remind the user to consider using environment variables or a secrets manager
- Note:
tokenundergateway.authis expected and should NOT be flagged - Note: Channel-specific tokens like
botToken(Telegram) SHOULD be flagged as WARN — they are required for operation but are high-value targets if the config leaks - Severity: MEDIUM — plaintext secrets in config files can be leaked through backups, logs, or version control
Step 8 — Reverse Proxy (trustedProxies)
- Path:
gateway.trustedProxies - Context: When OpenClaw sits behind nginx, Caddy, or any reverse proxy on the same machine, all connections appear to come from 127.0.0.1. Without
trustedProxies, the gateway treats every proxied request as a local client and skips auth. - PASS if
trustedProxiesis a non-empty array (proxy IPs are explicitly listed) - PASS if
trustedProxiesis absent or empty AND bind is"loopback"— print as:✅ PASS — no proxy, bind is loopback (set trustedProxies if you add one later) - WARN if
trustedProxiesis absent or empty AND bind is NOT"loopback"(e.g.,"lan") — the gateway is network-exposed and any proxy can spoof local access - Fix: Ask the user for their proxy IP(s) and set:
{ "gateway": { "trustedProxies": ["127.0.0.1"] } } - Severity: CRITICAL — this is the #1 real-world exploit vector (CVE-2025-49596)
Step 9 — Tailscale Exposure
- Path:
gateway.tailscale.mode - Expected:
"off" - Valid values (schema-enforced):
"off","serve","funnel" - PASS if the value is
"off"or the key is absent (default is"off") - WARN if the value is
"serve"— the gateway becomes reachable by all devices on your tailnet - FAIL if the value is
"funnel"— the gateway is exposed to the public internet via Tailscale Funnel - Fix: Set
gateway.tailscale.modeto"off":{ "gateway": { "tailscale": { "mode": "off" } } } - Severity: HIGH (serve — tailnet-only exposure) to CRITICAL (funnel — public internet exposure)
Step 10 — Directory Permissions
- Check: file mode of the
~/.clawdbot/directory itself - Run:
stat -f '%Lp' ~/.clawdbot/(macOS) orstat -c '%a' ~/.clawdbot/(Linux) - Expected:
700(owner only) - PASS if permissions are
700 - WARN if permissions are
755or750— other users can list filenames inside - FAIL if permissions are
777or anything world-writable - Fix: Run:
chmod 700 ~/.clawdbot/ - Severity: MEDIUM — even if individual files are 600, a listable directory leaks filenames and structure to other users on the system. Infostealers (RedLine, Lumma, Vidar) specifically target
~/.clawdbot/.
Step 11 — Browser Control Exposure
- Path:
browser.controlUrlandbrowser.controlToken - Context: OpenClaw can remote-control a browser. If
controlUrlis set butcontrolTokenis missing, anyone who knows the URL can hijack the browser session. - Also check
gateway.controlUi.allowInsecureAuth— iftrue, token auth is allowed over plain HTTP (tokens can be sniffed). - PASS if
browser.controlUrlis absent (browser control not configured) - PASS if
browser.controlUrlis set ANDbrowser.controlTokenis also set - FAIL if
browser.controlUrlis set butbrowser.controlTokenis missing or empty - WARN if
gateway.controlUi.allowInsecureAuthistrue— tokens sent over HTTP can be intercepted - Note: If both FAIL (missing token) and WARN (insecureAuth) trigger, report as 1 item with the highest severity (FAIL). Fix both.
- Fix: Set a control token:
Write the output into
openssl rand -hex 24browser.controlToken. IfallowInsecureAuthis true, set it to false:{ "gateway": { "controlUi": { "allowInsecureAuth": false } } } - Severity: HIGH — browser control without auth allows remote UI takeover and access to any logged-in sessions
Step 12 — Logging Redaction
- Path:
logging.redactSensitive - Expected:
"tools"(the only safe value besides being absent) - Valid values:
"off"or"tools"— there is no"all"option - PASS if the value is
"tools"or the key is absent (default is"tools") - WARN if the value is
"off"— sensitive tool output (API keys, tokens, credentials) will appear in plaintext in session logs - Fix: Set
logging.redactSensitiveto"tools":{ "logging": { "redactSensitive": "tools" } } - Severity: MEDIUM — with redaction off, any secret that passes through a tool call gets logged in plaintext at
~/.clawdbot/logs/
Step 13 — Control UI Exposure
- Path:
gateway.controlUi.enabled - Context: OpenClaw includes a web-based control dashboard. When enabled (the default), the dashboard is accessible on the gateway port. Combined with a non-loopback bind, this exposes the full control interface to the network.
- PASS if
gateway.controlUi.enabledisfalse - PASS if
gateway.controlUi.enabledistrue(or absent, default istrue) AND bind is"loopback"— dashboard only accessible locally - WARN if
gateway.controlUi.enabledistrue(or absent) AND bind is NOT"loopback"— dashboard exposed to network - Fix: Set
gateway.controlUi.enabledtofalse:{ "gateway": { "controlUi": { "enabled": false } } } - Severity: MEDIUM-HIGH — a network-exposed control UI lets anyone on the network interact with the agent dashboard
Step 14 — mDNS / Bonjour Broadcasting
- Check: Whether mDNS (Bonjour) service discovery is disabled
- Context: OpenClaw broadcasts
_clawdbot-gw._tcp.localvia mDNS by default, advertising detailed service information to all devices on the local network. TXT records include: gateway port, LAN hostname, display name, SSH port (default 22), CLI path, TLS fingerprint, canvas port, and tailnet DNS address (when applicable). This is controlled by the environment variableCLAWDBOT_DISABLE_BONJOUR, not by clawdbot.json. A watchdog re-advertises every 60 seconds. - Detection: In Step 0 you already ran
echo ${CLAWDBOT_DISABLE_BONJOUR:-unset}. Use that result here. - PASS if
CLAWDBOT_DISABLE_BONJOURis set to1 - WARN if
CLAWDBOT_DISABLE_BONJOURis unset or not1— your OpenClaw instance is advertising its presence and port to the entire LAN - Note: This cannot be fixed by editing clawdbot.json. The environment variable must be set in the shell profile or process environment.
- Fix (advisory): Add to your shell profile (
~/.zshrcor~/.bashrc):Then restart the gateway:export CLAWDBOT_DISABLE_BONJOUR=1clawdbot gateway restart - Severity: HIGH — passive information leak enables network reconnaissance; attackers on the same LAN can discover all OpenClaw instances without probing
Output format
After completing all checks, output a report in this exact format:
🔒 Security Check Report
1. Gateway Bind <ICON> <STATUS> — <detail>
2. Gateway Auth <ICON> <STATUS> — <detail>
3. Token Strength <ICON> <STATUS> — <detail>
4. DM Policy <ICON> <STATUS> — <detail>
5. Group Policy <ICON> <STATUS> — <detail>
6. File Permissions <ICON> <STATUS> — <detail>
7. Secrets Scan <ICON> <STATUS> — <detail>
8. Reverse Proxy <ICON> <STATUS> — <detail>
9. Tailscale <ICON> <STATUS> — <detail>
10. Directory Perms <ICON> <STATUS> — <detail>
11. Browser Control <ICON> <STATUS> — <detail>
12. Log Redaction <ICON> <STATUS> — <detail>
13. Control UI <ICON> <STATUS> — <detail>
14. mDNS Broadcasting <ICON> <STATUS> — <detail>
Score: X/14 PASS, Y WARN, Z FAIL
Where:
<ICON>is one of: ✅ (PASS), ⚠️ (WARN), ❌ (FAIL), ⏭️ (SKIP)<STATUS>is one of:PASS,WARN,FAIL,SKIP<detail>is a short explanation (e.g., "loopback", "token mode", "48 chars", "permissions 600")- SKIP items do not count toward the denominator. If 2 items are skipped, the score line reads
X/12notX/14
Auto-fix flow
If any item is FAIL or WARN, do the following:
- Show the report first (as above).
- List each fixable item with a short description of what will be changed.
- Ask the user: "Want me to fix these? (yes / no / pick)"
- yes — fix all FAIL and WARN items automatically, EXCEPT items marked "⚠️ NEEDS EXTRA CONFIRMATION" (#3 Token, #9 Tailscale) — those always require individual yes/no even in "yes" mode.
- no — stop, do nothing.
- pick — let the user choose which items to fix.
- Apply the fixes (see Fix recipes below). Items marked "NEEDS EXTRA CONFIRMATION" must be confirmed individually before applying.
- After applying, re-read the config and re-run the full check to confirm everything is PASS.
- If the config was changed, remind the user: "Run
clawdbot gateway restartto apply the new settings."
Fix recipes
Use these exact fixes for each item. Edit ~/.clawdbot/clawdbot.json using the edit/write tool.
#1 Gateway Bind — FAIL
Set gateway.bind to "loopback":
{ "gateway": { "bind": "loopback" } }
#2 Gateway Auth — WARN / FAIL
Set gateway.auth.mode to "token". If no token exists yet, also generate one:
{ "gateway": { "auth": { "mode": "token", "token": "<GENERATED>" } } }
Generate the token with:
openssl rand -hex 24
That produces a 48-character hex string (192-bit entropy).
#3 Token Strength — FAIL / WARN ⚠️ NEEDS EXTRA CONFIRMATION
Warning: Replacing the token disconnects ALL paired devices (Telegram, phones, other clients). They will need the new token to reconnect. Always ask the user before changing: "Replacing the gateway token will disconnect all paired devices. Proceed?" If confirmed, generate a new token:
openssl rand -hex 24
Write the output into gateway.auth.token.
#4 DM Policy — FAIL
Set dmPolicy to "pairing" for each affected channel:
{ "channels": { "<name>": { "dmPolicy": "pairing" } } }
#5 Group Policy — FAIL
Set groupPolicy to "allowlist" for each affected channel:
{ "channels": { "<name>": { "groupPolicy": "allowlist" } } }
#6 File Permissions — FAIL / WARN
Run:
chmod 600 ~/.clawdbot/clawdbot.json
#7 Secrets Scan — WARN
This one cannot be auto-fixed safely. Instead, list each flagged key and remind the user:
- Move the value to an environment variable
- Or use a secrets manager
- Reference it in the config as
"$ENV_VAR_NAME"if the platform supports it
#8 Reverse Proxy — WARN
Ask the user: "Are you running a reverse proxy (nginx, Caddy, etc.) in front of OpenClaw?"
- If yes: ask for the proxy IP(s) and set:
{ "gateway": { "trustedProxies": ["127.0.0.1"] } } - If no: mark as INFO/acknowledged, no config change needed
#9 Tailscale — WARN (serve) / FAIL (funnel) ⚠️ NEEDS EXTRA CONFIRMATION
Warning: Disabling Tailscale cuts off remote access for all tailnet devices. For "funnel" mode, disabling also removes public internet access.
Always ask the user before changing: "Disabling Tailscale mode means the gateway is no longer reachable from your tailnet (or from the public internet if using funnel). If you need remote access, use SSH tunneling instead. Proceed?"
If confirmed, set gateway.tailscale.mode to "off":
{ "gateway": { "tailscale": { "mode": "off" } } }
#10 Directory Permissions — WARN / FAIL
Run:
chmod 700 ~/.clawdbot/
#11 Browser Control — FAIL / WARN
If controlToken is missing, generate and set one:
openssl rand -hex 24
Write into browser.controlToken.
If allowInsecureAuth is true, set to false:
{ "gateway": { "controlUi": { "allowInsecureAuth": false } } }
#12 Logging Redaction — WARN
Set logging.redactSensitive to "tools":
{ "logging": { "redactSensitive": "tools" } }
#13 Control UI — WARN
Set gateway.controlUi.enabled to false:
{ "gateway": { "controlUi": { "enabled": false } } }
#14 mDNS Broadcasting — WARN
This one cannot be auto-fixed by editing clawdbot.json (it is controlled by an environment variable, not the config file). Instead, instruct the user:
- Add
export CLAWDBOT_DISABLE_BONJOUR=1to~/.zshrc(macOS) or~/.bashrc(Linux) - Then run
source ~/.zshrc && clawdbot gateway restart
Important rules for auto-fix
- Always back up first. Before writing any changes, copy the original:
cp ~/.clawdbot/clawdbot.json ~/.clawdbot/clawdbot.json.bak - Merge, don't overwrite. Read the full JSON, modify only the specific keys, write back the complete JSON. Never lose existing settings.
- Preserve formatting. Write the JSON with 2-space indentation.
- One write operation. Collect all JSON fixes, apply them in a single write to avoid partial states.
- Token replacement requires restart. If the gateway token was changed, the user must update any paired clients with the new token. Warn: "Your gateway token was changed. Any paired devices will need the new token to reconnect."
What this skill does NOT check
- Sandbox configuration (not needed for most setups)
- Network isolation / Docker (macOS native setups don't use it)
- MCP tool permissions (too complex for a basic audit)
- Whether your OS firewall is configured
- Whether your agent code has vulnerabilities
For a more comprehensive audit, see community tools like clawdbot-security-check.
Reference
Based on the community-compiled "Top 10 Clawdbot/Moltbot/OpenClaw Security Vulnerabilities" list, plus January 2026 disclosures (CVE-2025-49596 reverse proxy bypass, infostealer targeting, Tailscale exposure, browser control, logging redaction, mDNS broadcasting, control UI exposure). Covers 14 items for typical macOS-native deployments.
小安 Ann Agent — Taiwan 台灣 Building skills and local MCP services for all AI agents, everywhere. 為所有 AI Agent 打造技能與在地 MCP 服務,不限平台。