mohuclaw 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +64 -0
  3. package/bin/mohu-tui.js +73 -0
  4. package/bin/mohu-webui.js +67 -0
  5. package/dist/tui/tui.js +38733 -0
  6. package/dist/webui/index.html +1551 -0
  7. package/dist/webui/server.js +876 -0
  8. package/ioc/c2-ips.txt +25 -0
  9. package/ioc/file-hashes.txt +13 -0
  10. package/ioc/malicious-domains.txt +46 -0
  11. package/ioc/malicious-hashes.txt +5 -0
  12. package/ioc/malicious-publishers.txt +34 -0
  13. package/ioc/malicious-skill-patterns.txt +87 -0
  14. package/package.json +46 -0
  15. package/scripts/check/access_control.sh +183 -0
  16. package/scripts/check/credential_storage.sh +222 -0
  17. package/scripts/check/execution_sandbox.sh +502 -0
  18. package/scripts/check/memory_poisoning.sh +334 -0
  19. package/scripts/check/network_exposure.sh +479 -0
  20. package/scripts/check/resource_cost.sh +182 -0
  21. package/scripts/check/supply_chain.sh +553 -0
  22. package/scripts/repair/access_control/_common.sh +249 -0
  23. package/scripts/repair/access_control/check_1.sh +28 -0
  24. package/scripts/repair/access_control/check_2.sh +27 -0
  25. package/scripts/repair/access_control/check_3.sh +23 -0
  26. package/scripts/repair/access_control/check_4.sh +23 -0
  27. package/scripts/repair/access_control/check_5.sh +20 -0
  28. package/scripts/repair/credential_storage/_common.sh +277 -0
  29. package/scripts/repair/credential_storage/check_1.sh +47 -0
  30. package/scripts/repair/credential_storage/check_2.sh +35 -0
  31. package/scripts/repair/credential_storage/check_3.sh +53 -0
  32. package/scripts/repair/credential_storage/logs/security-scan.log +15 -0
  33. package/scripts/repair/execution_sandbox/_common.sh +302 -0
  34. package/scripts/repair/execution_sandbox/check_1.sh +67 -0
  35. package/scripts/repair/execution_sandbox/check_10.sh +23 -0
  36. package/scripts/repair/execution_sandbox/check_11.sh +34 -0
  37. package/scripts/repair/execution_sandbox/check_12.sh +38 -0
  38. package/scripts/repair/execution_sandbox/check_13.sh +29 -0
  39. package/scripts/repair/execution_sandbox/check_2.sh +46 -0
  40. package/scripts/repair/execution_sandbox/check_3.sh +37 -0
  41. package/scripts/repair/execution_sandbox/check_4.sh +23 -0
  42. package/scripts/repair/execution_sandbox/check_5.sh +28 -0
  43. package/scripts/repair/execution_sandbox/check_6.sh +17 -0
  44. package/scripts/repair/execution_sandbox/check_7.sh +17 -0
  45. package/scripts/repair/execution_sandbox/check_8.sh +17 -0
  46. package/scripts/repair/execution_sandbox/check_9.sh +17 -0
  47. package/scripts/repair/execution_sandbox/logs/security-scan.log +10 -0
  48. package/scripts/repair/memory_poisoning/_common.sh +336 -0
  49. package/scripts/repair/memory_poisoning/check_1.sh +51 -0
  50. package/scripts/repair/memory_poisoning/check_2.sh +26 -0
  51. package/scripts/repair/memory_poisoning/check_3.sh +24 -0
  52. package/scripts/repair/memory_poisoning/check_4.sh +27 -0
  53. package/scripts/repair/memory_poisoning/check_5.sh +20 -0
  54. package/scripts/repair/network_exposure/_common.sh +330 -0
  55. package/scripts/repair/network_exposure/check_1.sh +86 -0
  56. package/scripts/repair/network_exposure/check_10.sh +16 -0
  57. package/scripts/repair/network_exposure/check_11.sh +31 -0
  58. package/scripts/repair/network_exposure/check_12.sh +24 -0
  59. package/scripts/repair/network_exposure/check_2.sh +26 -0
  60. package/scripts/repair/network_exposure/check_3.sh +43 -0
  61. package/scripts/repair/network_exposure/check_4.sh +23 -0
  62. package/scripts/repair/network_exposure/check_5.sh +16 -0
  63. package/scripts/repair/network_exposure/check_6.sh +98 -0
  64. package/scripts/repair/network_exposure/check_7.sh +35 -0
  65. package/scripts/repair/network_exposure/check_8.sh +19 -0
  66. package/scripts/repair/network_exposure/check_9.sh +19 -0
  67. package/scripts/repair/resource_cost/_common.sh +303 -0
  68. package/scripts/repair/resource_cost/check_1.sh +16 -0
  69. package/scripts/repair/resource_cost/check_2.sh +16 -0
  70. package/scripts/repair/resource_cost/check_3.sh +23 -0
  71. package/scripts/repair/supply_chain/_common.sh +222 -0
  72. package/scripts/repair/supply_chain/check_1.sh +95 -0
  73. package/scripts/repair/supply_chain/check_10.sh +60 -0
  74. package/scripts/repair/supply_chain/check_11.sh +63 -0
  75. package/scripts/repair/supply_chain/check_12.sh +36 -0
  76. package/scripts/repair/supply_chain/check_13.sh +44 -0
  77. package/scripts/repair/supply_chain/check_14.sh +33 -0
  78. package/scripts/repair/supply_chain/check_15.sh +33 -0
  79. package/scripts/repair/supply_chain/check_16.sh +34 -0
  80. package/scripts/repair/supply_chain/check_17.sh +61 -0
  81. package/scripts/repair/supply_chain/check_18.sh +62 -0
  82. package/scripts/repair/supply_chain/check_2.sh +93 -0
  83. package/scripts/repair/supply_chain/check_3.sh +78 -0
  84. package/scripts/repair/supply_chain/check_4.sh +72 -0
  85. package/scripts/repair/supply_chain/check_5.sh +73 -0
  86. package/scripts/repair/supply_chain/check_6.sh +81 -0
  87. package/scripts/repair/supply_chain/check_7.sh +52 -0
  88. package/scripts/repair/supply_chain/check_8.sh +71 -0
  89. package/scripts/repair/supply_chain/check_9.sh +78 -0
  90. package/scripts/repair/supply_chain/logs/security-scan.log +77 -0
  91. package/scripts/scan.sh +228 -0
  92. package/webui/index.html +1551 -0
@@ -0,0 +1,330 @@
1
+ #!/bin/bash
2
+ # Exit codes: 0=SECURE, 1=WARNINGS, 2=COMPROMISED
3
+
4
+ set -uo pipefail
5
+
6
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ # PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
8
+ # IOC_DIR="$PROJECT_DIR/ioc"
9
+ PROJECT_DIR="$(cd "$SCRIPT_DIR/../../.." && pwd)"
10
+ IOC_DIR="$PROJECT_DIR/ioc"
11
+ SELF_DIR_NAME="$(basename "$PROJECT_DIR")"
12
+
13
+ # Default OpenClaw paths
14
+ # OPENCLAW_DIR="${OPENCLAW_HOME:-$HOME/.openclaw}"
15
+ OPENCLAW_DIR="${OPENCLAW_HOME:-$HOME/test/openclaw-1}"
16
+ SKILLS_DIR="$OPENCLAW_DIR/workspace/skills"
17
+ WORKSPACE_DIR="$OPENCLAW_DIR/workspace"
18
+ # LOG_DIR="$OPENCLAW_DIR/logs"
19
+ LOG_DIR="logs"
20
+ LOG_FILE="$LOG_DIR/security-scan.log"
21
+ TIMESTAMP="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
22
+
23
+ export PATH="$HOME/.local/bin:/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"
24
+
25
+ # Overall counters
26
+ CRITICAL=0
27
+ WARNINGS=0
28
+ CLEAN=0
29
+
30
+ # Per-category counters
31
+ CATEGORY_NAME=""
32
+ CATEGORY_TOTAL_CHECKS=0
33
+ CATEGORY_CRITICAL=0
34
+ CATEGORY_WARNINGS=0
35
+ CATEGORY_CLEAN=0
36
+
37
+ mkdir -p "$LOG_DIR"
38
+
39
+ log() {
40
+ echo "$1" | tee -a "$LOG_FILE"
41
+ }
42
+
43
+ header() {
44
+ # Usage: header <new_index> <message>
45
+ log ""
46
+ log "[$1/$CATEGORY_TOTAL_CHECKS] $2"
47
+ }
48
+
49
+ result_clean() {
50
+ log "CLEAN: $1"
51
+ CLEAN=$((CLEAN + 1))
52
+ CATEGORY_CLEAN=$((CATEGORY_CLEAN + 1))
53
+ }
54
+
55
+ result_warn() {
56
+ log "WARNING: $1"
57
+ WARNINGS=$((WARNINGS + 1))
58
+ CATEGORY_WARNINGS=$((CATEGORY_WARNINGS + 1))
59
+ }
60
+
61
+ result_critical() {
62
+ log "CRITICAL: $1"
63
+ CRITICAL=$((CRITICAL + 1))
64
+ CATEGORY_CRITICAL=$((CATEGORY_CRITICAL + 1))
65
+ }
66
+
67
+ category_start() {
68
+ # Usage: category_start <name> <total_checks>
69
+ CATEGORY_NAME="$1"
70
+ CATEGORY_TOTAL_CHECKS="$2"
71
+ CATEGORY_CRITICAL=0
72
+ CATEGORY_WARNINGS=0
73
+ CATEGORY_CLEAN=0
74
+
75
+ log ""
76
+ log "----------------------------------------"
77
+ log "CATEGORY START: $CATEGORY_NAME ($CATEGORY_TOTAL_CHECKS checks)"
78
+ log "----------------------------------------"
79
+ }
80
+
81
+ category_end() {
82
+ log ""
83
+ log "CATEGORY SUMMARY: $CATEGORY_NAME"
84
+ log " critical: $CATEGORY_CRITICAL"
85
+ log " warning : $CATEGORY_WARNINGS"
86
+ log " clean : $CATEGORY_CLEAN"
87
+ log "----------------------------------------"
88
+ }
89
+
90
+ # Use timeout if available (macOS may only have gtimeout via coreutils)
91
+ TIMEOUT_BIN=""
92
+ if command -v timeout >/dev/null 2>&1; then
93
+ TIMEOUT_BIN="timeout"
94
+ elif command -v gtimeout >/dev/null 2>&1; then
95
+ TIMEOUT_BIN="gtimeout"
96
+ fi
97
+
98
+ run_with_timeout() {
99
+ local secs="$1"
100
+ shift
101
+
102
+ if [ -n "$TIMEOUT_BIN" ]; then
103
+ "$TIMEOUT_BIN" "$secs" "$@"
104
+ elif command -v python3 >/dev/null 2>&1; then
105
+ python3 - "$secs" "$@" <<'PY'
106
+ import subprocess
107
+ import sys
108
+
109
+ def main():
110
+ try:
111
+ secs = float(sys.argv[1])
112
+ except Exception:
113
+ secs = 0
114
+
115
+ cmd = sys.argv[2:]
116
+ if not cmd:
117
+ sys.exit(1)
118
+
119
+ try:
120
+ proc = subprocess.Popen(cmd)
121
+ try:
122
+ proc.wait(timeout=secs if secs > 0 else None)
123
+ except subprocess.TimeoutExpired:
124
+ proc.kill()
125
+ proc.wait()
126
+ sys.exit(124)
127
+ sys.exit(proc.returncode if proc.returncode is not None else 0)
128
+ except FileNotFoundError:
129
+ sys.exit(127)
130
+
131
+ if __name__ == "__main__":
132
+ main()
133
+ PY
134
+ else
135
+ "$@"
136
+ fi
137
+ }
138
+
139
+ # Load IOC data
140
+ load_ips() {
141
+ if [ -f "$IOC_DIR/c2-ips.txt" ]; then
142
+ grep -v '^#' "$IOC_DIR/c2-ips.txt" | grep -v '^$' | cut -d'|' -f1
143
+ else
144
+ echo "91.92.242"
145
+ fi
146
+ }
147
+
148
+ load_domains() {
149
+ if [ -f "$IOC_DIR/malicious-domains.txt" ]; then
150
+ grep -v '^#' "$IOC_DIR/malicious-domains.txt" | grep -v '^$' | cut -d'|' -f1
151
+ else
152
+ echo "webhook.site"
153
+ fi
154
+ }
155
+
156
+ sha256_file() {
157
+ # Cross-platform SHA-256 for a file
158
+ local target="$1"
159
+ [ -f "$target" ] || return 1
160
+
161
+ if command -v sha256sum >/dev/null 2>&1; then
162
+ sha256sum "$target" 2>/dev/null | awk '{print tolower($1)}'
163
+ elif command -v shasum >/dev/null 2>&1; then
164
+ shasum -a 256 "$target" 2>/dev/null | awk '{print tolower($1)}'
165
+ elif command -v openssl >/dev/null 2>&1; then
166
+ openssl dgst -sha256 "$target" 2>/dev/null | sed -E 's/^.*= //' | tr '[:upper:]' '[:lower:]'
167
+ else
168
+ return 1
169
+ fi
170
+ }
171
+
172
+ load_hash_iocs() {
173
+ # Expected format: <sha256>|<campaign>
174
+ # Similar to c2-ips.txt storage style
175
+ if [ -f "$IOC_DIR/malicious-hashes.txt" ]; then
176
+ grep -v '^#' "$IOC_DIR/malicious-hashes.txt" | grep -v '^$' || true
177
+ fi
178
+ }
179
+
180
+ lookup_malicious_hash_campaign() {
181
+ local needle
182
+ needle="$(printf "%s" "${1:-}" | tr '[:upper:]' '[:lower:]')"
183
+ [ -n "$needle" ] || return 1
184
+
185
+ while IFS='|' read -r hash_val campaign rest; do
186
+ hash_val="$(printf "%s" "$hash_val" | tr '[:upper:]' '[:lower:]')"
187
+ if [ "$hash_val" = "$needle" ]; then
188
+ printf "%s\n" "${campaign:-unknown}"
189
+ return 0
190
+ fi
191
+ done < <(load_hash_iocs) # ← 进程替换,不产生子shell
192
+
193
+ return 1
194
+ }
195
+
196
+ extract_github_account_age_days() {
197
+ # Best-effort local metadata extraction only.
198
+ # We cannot reliably infer GitHub account age from filesystem alone unless
199
+ # the skill metadata explicitly records it.
200
+ local skill_dir="$1"
201
+ local val=""
202
+
203
+ for meta in "$skill_dir/package.json" "$skill_dir/config.json" "$skill_dir/SKILL.md"; do
204
+ [ -f "$meta" ] || continue
205
+
206
+ # JSON-ish keys
207
+ val="$(grep -iEo '"(githubAccountAge|github_account_age|accountAgeDays|githubAccountAgeDays)"[[:space:]]*:[[:space:]]*[0-9]+' "$meta" 2>/dev/null | head -1 | grep -oE '[0-9]+' || true)"
208
+ if [ -n "$val" ]; then
209
+ printf "%s\n" "$val"
210
+ return 0
211
+ fi
212
+
213
+ # YAML / markdown frontmatter-ish keys
214
+ val="$(grep -iE '^(githubAccountAge|github_account_age|accountAgeDays|githubAccountAgeDays)[[:space:]]*:[[:space:]]*[0-9]+' "$meta" 2>/dev/null | head -1 | grep -oE '[0-9]+' || true)"
215
+ if [ -n "$val" ]; then
216
+ printf "%s\n" "$val"
217
+ return 0
218
+ fi
219
+ done
220
+
221
+ return 1
222
+ }
223
+
224
+
225
+ export PATH="$HOME/.local/bin:/opt/homebrew/opt/node@22/bin:/opt/homebrew/bin:/usr/local/bin:$PATH"
226
+
227
+ # ------------------------------------------------------------
228
+ # Shared helpers
229
+ # ------------------------------------------------------------
230
+
231
+ OPENCLAW_PRESENT=false
232
+ if command -v openclaw >/dev/null 2>&1; then
233
+ OPENCLAW_PRESENT=true
234
+ fi
235
+
236
+ OC_VERSION="unknown"
237
+ PARSED_OC_VERSION=""
238
+ OC_MAJOR=""
239
+ OC_MINOR=""
240
+ OC_PATCH=""
241
+
242
+ if [ "$OPENCLAW_PRESENT" = true ]; then
243
+ OC_VERSION="$(run_with_timeout 5 openclaw --version 2>/dev/null || echo "unknown")"
244
+ PARSED_OC_VERSION="$(echo "$OC_VERSION" | grep -oE '[0-9]{4}\.[0-9]+\.[0-9]+' | head -1 || true)"
245
+ if [ -n "$PARSED_OC_VERSION" ]; then
246
+ OC_MAJOR="$(echo "$PARSED_OC_VERSION" | cut -d'.' -f1)"
247
+ OC_MINOR="$(echo "$PARSED_OC_VERSION" | cut -d'.' -f2)"
248
+ OC_PATCH="$(echo "$PARSED_OC_VERSION" | cut -d'.' -f3)"
249
+ fi
250
+ fi
251
+
252
+ get_oc_config() {
253
+ # Usage: get_oc_config <key> <default>
254
+ local key="$1"
255
+ local default_val="${2:-}"
256
+ if [ "$OPENCLAW_PRESENT" = true ]; then
257
+ run_with_timeout 10 openclaw config get "$key" 2>/dev/null || echo "$default_val"
258
+ else
259
+ echo "$default_val"
260
+ fi
261
+ }
262
+
263
+ normalize_config_val() {
264
+ # Normalize null/undefined-ish values to empty string
265
+ local val="${1:-}"
266
+ case "$val" in
267
+ null|undefined|"")
268
+ echo ""
269
+ ;;
270
+ *)
271
+ echo "$val"
272
+ ;;
273
+ esac
274
+ }
275
+
276
+ version_ge() {
277
+ # Usage: version_ge <major> <minor> <patch>
278
+ # returns 0 if OC_VERSION >= target, else 1
279
+ local t_major="$1"
280
+ local t_minor="$2"
281
+ local t_patch="$3"
282
+
283
+ if [ -z "$PARSED_OC_VERSION" ]; then
284
+ return 1
285
+ fi
286
+
287
+ if [ "$OC_MAJOR" -gt "$t_major" ] 2>/dev/null; then
288
+ return 0
289
+ fi
290
+ if [ "$OC_MAJOR" -lt "$t_major" ] 2>/dev/null; then
291
+ return 1
292
+ fi
293
+
294
+ if [ "$OC_MINOR" -gt "$t_minor" ] 2>/dev/null; then
295
+ return 0
296
+ fi
297
+ if [ "$OC_MINOR" -lt "$t_minor" ] 2>/dev/null; then
298
+ return 1
299
+ fi
300
+
301
+ if [ "$OC_PATCH" -ge "$t_patch" ] 2>/dev/null; then
302
+ return 0
303
+ fi
304
+
305
+ return 1
306
+ }
307
+
308
+ version_lt() {
309
+ # Usage: version_lt <major> <minor> <patch>
310
+ # returns 0 if OC_VERSION < target, else 1
311
+ if [ -z "$PARSED_OC_VERSION" ]; then
312
+ return 1
313
+ fi
314
+ if version_ge "$1" "$2" "$3"; then
315
+ return 1
316
+ fi
317
+ return 0
318
+ }
319
+
320
+ detect_gateway_port() {
321
+ local raw
322
+ raw="$(get_oc_config "gateway.port" "18789")"
323
+ raw="$(echo "$raw" | grep -oE '[0-9]+' | head -1 || true)"
324
+ if [ -z "$raw" ]; then
325
+ raw="18789"
326
+ fi
327
+ echo "$raw"
328
+ }
329
+
330
+ GW_PORT="$(detect_gateway_port)"
@@ -0,0 +1,86 @@
1
+ #!/bin/bash
2
+ # CHECK 1 (origin 13): Gateway Security Configuration
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
5
+ source "$SCRIPT_DIR/_common.sh"
6
+
7
+ # Environment vars (set by caller / _common.sh sourced before this):
8
+ # AUTO_FIX — if "1", automatically remove the offending skill
9
+ # Example: AUTO_FIX=1 ./check_1.sh
10
+
11
+ GW_ISSUES=0
12
+ BIND="unknown"
13
+ AUTH_MODE="unknown"
14
+
15
+ if [ "$OPENCLAW_PRESENT" = true ]; then
16
+ log " OpenClaw version: $OC_VERSION"
17
+
18
+ BIND="$(get_oc_config "gateway.bind" "unknown")"
19
+ if [ "$BIND" = "lan" ] || [ "$BIND" = "0.0.0.0" ]; then
20
+ GW_ISSUES=$((GW_ISSUES + 1))
21
+ fi
22
+
23
+ AUTH_MODE="$(get_oc_config "gateway.auth.mode" "unknown")"
24
+ if [ "$AUTH_MODE" = "none" ] || [ "$AUTH_MODE" = "off" ]; then
25
+ GW_ISSUES=$((GW_ISSUES + 1))
26
+ fi
27
+ else
28
+ log " openclaw command not found"
29
+ fi
30
+
31
+ # Auto-fix
32
+ if [ "${AUTO_FIX:-0}" = "1" ]; then
33
+ FIXED=0
34
+ FAILED=0
35
+
36
+ if [ "$BIND" = "lan" ] || [ "$BIND" = "0.0.0.0" ]; then
37
+ log "AUTO-FIX: Setting gateway.bind to localhost..."
38
+ if openclaw config set gateway.bind localhost >> "$LOG_FILE" 2>&1; then
39
+ log "SUCCESS: gateway.bind set to localhost"
40
+ FIXED=$((FIXED + 1))
41
+ else
42
+ log "ERROR: Failed to set gateway.bind"
43
+ FAILED=$((FAILED + 1))
44
+ fi
45
+ fi
46
+
47
+ if [ "$AUTH_MODE" = "none" ] || [ "$AUTH_MODE" = "off" ]; then
48
+ log "AUTO-FIX: Setting gateway.auth.mode to token..."
49
+ if openclaw config set gateway.auth.mode token >> "$LOG_FILE" 2>&1; then
50
+ log "SUCCESS: gateway.auth.mode set to token"
51
+ FIXED=$((FIXED + 1))
52
+ else
53
+ log "ERROR: Failed to set gateway.auth.mode"
54
+ FAILED=$((FAILED + 1))
55
+ fi
56
+ fi
57
+
58
+ log "Auto-fix complete: $FIXED fixed, $FAILED failed"
59
+ if [ $FIXED -gt 0 ]; then
60
+ log "NOTE: Restart OpenClaw for changes to take effect: openclaw restart"
61
+ fi
62
+ exit 0
63
+ fi
64
+
65
+ # Guidance
66
+ cat <<EOF
67
+ Found $GW_ISSUES gateway configuration issue(s).
68
+ An exposed or unauthenticated gateway allows anyone on the network to access OpenClaw.
69
+
70
+ RECOMMENDED ACTIONS:
71
+ 1. Bind gateway to localhost only (current: $BIND)
72
+ openclaw config set gateway.bind localhost
73
+
74
+ 2. Enable gateway authentication (current: $AUTH_MODE)
75
+ openclaw config set gateway.auth.mode token
76
+
77
+ 3. Restart OpenClaw to apply changes
78
+ openclaw restart
79
+
80
+ 4. Verify current gateway config
81
+ openclaw config get gateway
82
+
83
+ auto-fix
84
+ EOF
85
+
86
+ exit 1
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+ # CHECK 10 (origin 39/45): Deep Link + Sandbox Browser Bridge
3
+ # Usage: ./check_10.sh
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ source "$SCRIPT_DIR/_common.sh"
7
+
8
+ # Guidance
9
+ cat <<EOF
10
+ RECOMMENDED ACTIONS:
11
+ 1. Update OpenClaw:
12
+ openclaw update
13
+
14
+ EOF
15
+
16
+ exit 0
@@ -0,0 +1,31 @@
1
+ #!/bin/bash
2
+ # CHECK 11 (new / GW-003): Weak gateway auth token/password
3
+ # Usage: ./check_11.sh
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ source "$SCRIPT_DIR/_common.sh"
7
+
8
+
9
+ # Guidance
10
+ cat <<EOF
11
+ RECOMMENDED ACTIONS:
12
+ 1. Generate a strong random token:
13
+ openssl rand -hex 16
14
+
15
+ 2. Set the new token:
16
+ openclaw config set gateway.auth.password <new-token>
17
+
18
+ 3. Or set token mode and update:
19
+ openclaw config set gateway.auth.mode token
20
+ openclaw config set gateway.auth.token <new-token>
21
+
22
+ 4. Verify the new token length:
23
+ openclaw config get gateway.auth.password | wc -c
24
+ # Should be 32 or more
25
+
26
+ 5. Restart OpenClaw to apply changes:
27
+ openclaw restart
28
+
29
+ EOF
30
+
31
+ exit 0
@@ -0,0 +1,24 @@
1
+ #!/bin/bash
2
+ # CHECK 12 (new / GW-006): Gateway TLS enabled
3
+ # Usage: ./check_12.sh
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ source "$SCRIPT_DIR/_common.sh"
7
+
8
+ # Guidance
9
+ cat <<EOF
10
+ RECOMMENDED ACTIONS:
11
+ 1. Enable TLS on the gateway:
12
+ openclaw config set gateway.tls.enabled true
13
+
14
+ 2. Provide your TLS certificate and key via OpenClaw config:
15
+ openclaw config set gateway.tls.certFile /path/to/cert.pem
16
+ openclaw config set gateway.tls.keyFile /path/to/key.pem
17
+
18
+ 3. Restart OpenClaw to apply changes:
19
+ openclaw restart
20
+
21
+ 4. Consult OpenClaw documentation for TLS configuration details.
22
+ EOF
23
+
24
+ exit 0
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+ # CHECK 2 (origin 14): WebSocket Origin Validation
3
+ # Usage: ./check_2.sh
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ source "$SCRIPT_DIR/_common.sh"
7
+
8
+ # Guidance
9
+ cat << EOF
10
+ RECOMMENDED ACTIONS:
11
+ 1. Update OpenClaw immediately:
12
+ openclaw update
13
+
14
+ 2. Enable gateway authentication as an additional mitigation:
15
+ openclaw config set gateway.auth.mode token
16
+ openclaw config set gateway.auth.token \$(openssl rand -hex 16)
17
+
18
+ 3. Bind gateway to localhost only:
19
+ openclaw config set gateway.bind localhost
20
+
21
+ 4. Restart OpenClaw to apply changes:
22
+ openclaw restart
23
+
24
+ EOF
25
+
26
+ exit 0
@@ -0,0 +1,43 @@
1
+ #!/bin/bash
2
+ # CHECK 3 (origin 25): Reverse Proxy / Localhost Trust Bypass
3
+ # Usage: ./check_3.sh
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ source "$SCRIPT_DIR/_common.sh"
7
+
8
+ # Environment vars (set by caller / _common.sh sourced before this):
9
+ # AUTO_FIX — if "1", automatically remove the offending skill
10
+ # Example: AUTO_FIX=1 ./check_3.sh
11
+
12
+ # Auto-fix
13
+ if [ "${AUTO_FIX:-0}" = "1" ]; then
14
+ if [ "$DISABLE_DEVICE_AUTH" = "true" ]; then
15
+ log "AUTO-FIX: Re-enabling device authentication..."
16
+ if openclaw config set gateway.dangerouslyDisableDeviceAuth false >> "$LOG_FILE" 2>&1; then
17
+ log "SUCCESS: Device authentication re-enabled"
18
+ else
19
+ log "ERROR: Failed to re-enable device authentication"
20
+ fi
21
+ fi
22
+ exit 0
23
+ fi
24
+
25
+ # Guidance
26
+ cat <<EOF
27
+ RECOMMENDED ACTIONS:
28
+ 1. Re-enable device authentication:
29
+ openclaw config set gateway.dangerouslyDisableDeviceAuth false
30
+
31
+ 2. Bind gateway to localhost instead of LAN:
32
+ openclaw config set gateway.bind localhost
33
+
34
+ 3. If reverse proxy is needed, configure trusted proxies explicitly:
35
+ openclaw config set gateway.trustedProxies '["127.0.0.1"]'
36
+
37
+ 4. Restart OpenClaw to apply changes:
38
+ openclaw restart
39
+
40
+ auto-fix
41
+ EOF
42
+
43
+ exit 0
@@ -0,0 +1,23 @@
1
+ #!/bin/bash
2
+ # CHECK 4 (origin 33): ClawJacked Brute-Force Protection
3
+ # Usage: ./check_4.sh
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ source "$SCRIPT_DIR/_common.sh"
7
+
8
+ # Guidance
9
+ cat << EOF
10
+ RECOMMENDED ACTIONS:
11
+ 1. Update OpenClaw immediately:
12
+ openclaw update
13
+
14
+ 2. Set a strong gateway password (if not already set):
15
+ openclaw config set gateway.auth.mode token
16
+ openclaw config set gateway.auth.token <strong-random-token>
17
+
18
+ 3. Verify rate limiting is enabled after update:
19
+ openclaw config get gateway.auth.rateLimit
20
+
21
+ EOF
22
+
23
+ exit 0
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+ # CHECK 5 (origin 41): Browser Relay CDP Unauthenticated Access
3
+ # Usage: ./check_5.sh
4
+
5
+ # Guidance
6
+ cat << EOF
7
+ RECOMMENDED ACTIONS:
8
+ 1. Update OpenClaw immediately:
9
+ openclaw update
10
+
11
+ 2. Disable Browser Relay until patched:
12
+ openclaw config set browser.relay.enabled false
13
+
14
+ EOF
15
+
16
+ exit 0
@@ -0,0 +1,98 @@
1
+ #!/bin/bash
2
+ # CHECK 6 (origin 31): Internet Exposure Detection
3
+ # Usage: ./check_6.sh
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ source "$SCRIPT_DIR/_common.sh"
7
+
8
+ OC_PORT="$(openclaw config get gateway.port 2>/dev/null || echo "3000")"
9
+
10
+ if command -v firewall-cmd &>/dev/null && firewall-cmd --state &>/dev/null 2>&1; then
11
+ FW_TYPE="firewalld"
12
+ elif command -v ufw &>/dev/null; then
13
+ FW_TYPE="ufw"
14
+ else
15
+ FW_TYPE="iptables"
16
+ fi
17
+
18
+ case "$FW_TYPE" in
19
+ firewalld)
20
+ cat <<EOF
21
+ RECOMMENDED ACTIONS:
22
+ 1. Block OpenClaw port from external access:
23
+ sudo firewall-cmd --permanent --remove-port=$OC_PORT/tcp
24
+ sudo firewall-cmd --reload
25
+
26
+ 2. Allow only localhost access (if needed):
27
+ sudo firewall-cmd --permanent --zone=trusted --add-source=127.0.0.1
28
+ sudo firewall-cmd --permanent --zone=trusted --add-port=$OC_PORT/tcp
29
+ sudo firewall-cmd --reload
30
+
31
+ 3. Verify rules:
32
+ sudo firewall-cmd --list-all
33
+
34
+ 4. Check status:
35
+ sudo firewall-cmd --state
36
+
37
+ EOF
38
+ ;;
39
+ ufw)
40
+ cat <<EOF
41
+ ==========================================
42
+ GUIDANCE: Manual Review Required
43
+ ==========================================
44
+ Linux Firewall Configuration (ufw)
45
+
46
+ RECOMMENDED ACTIONS:
47
+ 1. Enable ufw if not already enabled:
48
+ sudo ufw enable
49
+
50
+ 2. Deny OpenClaw port by default:
51
+ sudo ufw deny $OC_PORT/tcp
52
+
53
+ 3. Allow only localhost access:
54
+ sudo ufw allow from 127.0.0.1 to any port $OC_PORT proto tcp
55
+
56
+ 4. Verify rules:
57
+ sudo ufw status verbose
58
+
59
+ 5. Check numbered rules:
60
+ sudo ufw status numbered
61
+
62
+ EOF
63
+ ;;
64
+ iptables)
65
+ cat <<EOF
66
+ ==========================================
67
+ GUIDANCE: Manual Review Required
68
+ ==========================================
69
+ Linux Firewall Configuration (iptables)
70
+
71
+ RECOMMENDED ACTIONS:
72
+ 1. Allow localhost access only:
73
+ sudo iptables -A INPUT -p tcp --dport $OC_PORT -s 127.0.0.1 -j ACCEPT
74
+ sudo iptables -A INPUT -p tcp --dport $OC_PORT -j DROP
75
+
76
+ 2. For IPv6:
77
+ sudo ip6tables -A INPUT -p tcp --dport $OC_PORT -s ::1 -j ACCEPT
78
+ sudo ip6tables -A INPUT -p tcp --dport $OC_PORT -j DROP
79
+
80
+ 3. Save rules (Debian/Ubuntu):
81
+ sudo apt-get install iptables-persistent
82
+ sudo netfilter-persistent save
83
+
84
+ 4. Save rules (RHEL/CentOS):
85
+ sudo service iptables save
86
+
87
+ 5. Verify rules:
88
+ sudo iptables -L -n -v
89
+
90
+ 6. Make persistent across reboots:
91
+ sudo systemctl enable iptables
92
+ sudo systemctl enable ip6tables
93
+
94
+ EOF
95
+ ;;
96
+ esac
97
+
98
+ exit 0