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,23 @@
1
+ #!/bin/bash
2
+ # CHECK 4 (origin 35): Exec safeBins Validation Bypass
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. Audit safeBins configuration:
15
+ openclaw config get tools.exec.safeBins
16
+
17
+ 3. Consider removing 'sort' from safeBins until patched:
18
+ openclaw config set tools.exec.safeBins <updated-list>
19
+
20
+ EOF
21
+
22
+ exit 0
23
+
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+ # CHECK 5 (origin 37): PATH Hijacking / Command Hijacking
3
+ # Usage: ./check_5.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. Review and remove suspicious executables flagged above (check logs for exact paths)
12
+
13
+ 2. Verify which binary is actually being used:
14
+ which -a node python3 bash curl git openclaw
15
+
16
+ 3. Check for planted executables in workspace:
17
+ find $WORKSPACE_DIR -maxdepth 3 -type f -executable -name "node" -o -name "python3" -o -name "bash" -o -name "curl" -o -name "git"
18
+
19
+ 4. Ensure user-writable directories appear AFTER system directories in PATH:
20
+ echo \$PATH
21
+ # /usr/local/bin and /usr/bin should come before ~/bin etc.
22
+
23
+ 5. Remove or investigate any non-whitelisted writable directories from PATH:
24
+ export PATH="/usr/local/bin:/usr/bin:/bin"
25
+
26
+ EOF
27
+
28
+ exit 0
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ # CHECK 6 (origin 43): Exec-Approvals Shell Expansion Bypass
3
+ # Usage: ./check_6.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
+ EOF
15
+
16
+ exit 0
17
+
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ # CHECK 7 (origin 44): Approval Field Injection / Exec Gating Bypass
3
+ # Usage: ./check_7.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
+ EOF
15
+
16
+ exit 0
17
+
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ # CHECK 8 (origin 42): Browser Control API Path Traversal
3
+ # Usage: ./check_8.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
+ EOF
15
+
16
+ exit 0
17
+
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ # CHECK 9 (origin 47): TAR Archive Path Traversal
3
+ # Usage: ./check_9.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
+ EOF
15
+
16
+ exit 0
17
+
@@ -0,0 +1,10 @@
1
+ Auto-fix complete: 0 fixed, 0 failed
2
+ Auto-fix complete: 0 fixed, 0 failed
3
+ Auto-fix complete: 0 fixed, 0 failed
4
+ Auto-fix complete: 0 fixed, 0 failed
5
+ Auto-fix complete: 0 fixed, 0 failed
6
+ Auto-fix complete: 0 fixed, 0 failed
7
+ Auto-fix complete: 0 fixed, 0 failed
8
+ Auto-fix complete: 0 fixed, 0 failed
9
+ Auto-fix complete: 0 fixed, 0 failed
10
+ Auto-fix complete: 0 fixed, 0 failed
@@ -0,0 +1,336 @@
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
+ OPENCLAW_PRESENT=false
226
+ if command -v openclaw >/dev/null 2>&1; then
227
+ OPENCLAW_PRESENT=true
228
+ fi
229
+
230
+ has_pcre_grep() {
231
+ echo 'test' | grep -P 't.st' >/dev/null 2>&1
232
+ }
233
+
234
+ get_oc_config() {
235
+ # Usage: get_oc_config <key> <default>
236
+ local key="$1"
237
+ local default_val="${2:-}"
238
+ if [ "$OPENCLAW_PRESENT" = true ]; then
239
+ run_with_timeout 10 openclaw config get "$key" 2>/dev/null || echo "$default_val"
240
+ else
241
+ echo "$default_val"
242
+ fi
243
+ }
244
+
245
+ normalize_config_val() {
246
+ local val="${1:-}"
247
+ case "$val" in
248
+ null|undefined|"")
249
+ echo ""
250
+ ;;
251
+ *)
252
+ echo "$val"
253
+ ;;
254
+ esac
255
+ }
256
+
257
+ get_perm() {
258
+ local target="$1"
259
+
260
+ [ -e "$target" ] || {
261
+ echo "unknown"
262
+ return
263
+ }
264
+
265
+ case "$(uname -s)" in
266
+ Darwin|FreeBSD|OpenBSD|NetBSD)
267
+ stat -f '%Lp' "$target" 2>/dev/null || echo "unknown"
268
+ ;;
269
+ Linux)
270
+ stat -c '%a' "$target" 2>/dev/null || echo "unknown"
271
+ ;;
272
+ *)
273
+ stat -c '%a' "$target" 2>/dev/null || stat -f '%Lp' "$target" 2>/dev/null || echo "unknown"
274
+ ;;
275
+ esac
276
+ }
277
+
278
+ list_memory_files() {
279
+ # Enumerate workspace-level and agent-level memory files
280
+ local f
281
+ for f in \
282
+ "$WORKSPACE_DIR/SOUL.md" \
283
+ "$WORKSPACE_DIR/MEMORY.md" \
284
+ "$WORKSPACE_DIR/IDENTITY.md"
285
+ do
286
+ [ -f "$f" ] && echo "$f"
287
+ done
288
+
289
+ if [ -d "$OPENCLAW_DIR/agents" ]; then
290
+ find "$OPENCLAW_DIR/agents" -mindepth 2 -maxdepth 2 -type f \
291
+ \( -name 'soul.md' -o -name 'SOUL.md' -o -name 'MEMORY.md' -o -name 'IDENTITY.md' \) \
292
+ 2>/dev/null || true
293
+ fi
294
+ }
295
+
296
+ extract_allowed_domains() {
297
+ # Build allowlist from config + defaults
298
+ # Defaults follow the TS snippet.
299
+ local cfg raw_domains
300
+ cfg="$(normalize_config_val "$(get_oc_config "secureclaw.network.egressAllowlist" "")")"
301
+
302
+ {
303
+ echo "api.anthropic.com"
304
+ echo "api.openai.com"
305
+ echo "generativelanguage.googleapis.com"
306
+ if [ -n "$cfg" ]; then
307
+ echo "$cfg" | grep -oE '[A-Za-z0-9.-]+\.[A-Za-z]{2,}' || true
308
+ fi
309
+ } | awk 'NF' | sort -u
310
+ }
311
+
312
+ url_host_allowed() {
313
+ # Usage: url_host_allowed <hostname>
314
+ local host="${1:-}"
315
+ local allowed
316
+ [ -n "$host" ] || return 1
317
+
318
+ while IFS= read -r allowed; do
319
+ [ -z "$allowed" ] && continue
320
+ if [ "$host" = "$allowed" ]; then
321
+ return 0
322
+ fi
323
+ case "$host" in
324
+ *."$allowed")
325
+ return 0
326
+ ;;
327
+ esac
328
+ done <<EOF
329
+ $ALLOWED_DOMAINS
330
+ EOF
331
+
332
+ return 1
333
+ }
334
+
335
+ # Precompute allowed domains once
336
+ ALLOWED_DOMAINS="$(extract_allowed_domains)"
@@ -0,0 +1,51 @@
1
+ #!/bin/bash
2
+ # CHECK 1 (origin 10 + expanded patterns): Memory Poisoning Detection
3
+ # Usage: ./check_1.sh
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ source "$SCRIPT_DIR/_common.sh"
7
+
8
+ MEMORY_POISON=0
9
+ MEMORY_FILES_FOUND=0
10
+ FOUND_FILES=()
11
+
12
+ while IFS= read -r memfile; do
13
+ [ -z "$memfile" ] && continue
14
+ [ -f "$memfile" ] || continue
15
+
16
+ MEMORY_FILES_FOUND=$((MEMORY_FILES_FOUND + 1))
17
+
18
+ POISON_HITS="$(grep -inE \
19
+ 'ignore[[:space:]]+previous[[:space:]]+instructions|ignore[[:space:]]+all[[:space:]]+previous|disregard[[:space:]]+(all[[:space:]]+)?previous|override.*instruction|new[[:space:]]+system[[:space:]]+prompt|system[[:space:]]+prompt|forget.*previous|you[[:space:]]+are[[:space:]]+now|act[[:space:]]+as[[:space:]]+if|pretend[[:space:]]+to[[:space:]]+be|from[[:space:]]+now[[:space:]]+on.*ignore|forward[[:space:]]+to|send[[:space:]]+to|exfiltrat(e|ion)|leak[[:space:]]+(the[[:space:]]+)?(secret|token|credential|key)|reveal[[:space:]]+(the[[:space:]]+)?(system[[:space:]]+prompt|secret|token|credential|key)|post[[:space:]]+to[[:space:]]+https?://|upload[[:space:]]+to[[:space:]]+https?://' \
20
+ "$memfile" 2>/dev/null || true)"
21
+
22
+ if [ -n "$POISON_HITS" ]; then
23
+ MEMORY_POISON=$((MEMORY_POISON + 1))
24
+ FOUND_FILES+=("$memfile")
25
+ fi
26
+ done <<EOF
27
+ $(list_memory_files)
28
+ EOF
29
+
30
+ # 生成文件路径列表
31
+ FILE_LIST=""
32
+ for f in "${FOUND_FILES[@]}"; do
33
+ FILE_LIST="${FILE_LIST} $f\n"
34
+ done
35
+
36
+ # Guidance
37
+ cat <<EOF
38
+ RECOMMENDED ACTIONS:
39
+ 1. Inspect the flagged memory files:
40
+ $(printf "%b" "$FILE_LIST")
41
+
42
+ 2. Remove any lines containing prompt injection patterns
43
+
44
+ 3. If the file has been heavily tampered with, restore from a known-good backup or recreate it from scratch
45
+
46
+ 4. Clear Agent memory if compromise is suspected:
47
+ openclaw memory clear
48
+
49
+ EOF
50
+
51
+ exit 0
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+ # CHECK 2 (origin 40): Log Poisoning / WebSocket Header Injection
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. Enable WebSocket header redaction:
12
+ openclaw config set logging.redactHeaders true
13
+
14
+ 2. Strip ANSI escape sequences from logs:
15
+ sed -i 's/\x1b\[[0-9;]*[a-zA-Z]//g' $LOG_DIR/*.log
16
+
17
+ 3. Strip control characters from logs:
18
+ for f in $LOG_DIR/*.log; do tr -d '\000-\010\016-\037' < "\$f" > "\$f.clean" && mv "\$f.clean" "\$f"; done
19
+
20
+ 4. Restart OpenClaw to apply config changes:
21
+ openclaw restart
22
+
23
+ EOF
24
+
25
+ exit 0
26
+
@@ -0,0 +1,24 @@
1
+ #!/bin/bash
2
+ # CHECK 3 (new / MEM-003): Base64 encoded blocks in memory
3
+ # Usage: ./check_3.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. Inspect the flagged memory files and decode suspicious blocks manually:
12
+ base64 -d <<< "<paste-base64-string>"
13
+
14
+ 2. If the decoded content contains suspicious instructions (API calls, exfiltration), delete the memory file immediately
15
+
16
+ 3. Review which skill or conversation created this memory entry.
17
+
18
+ 4. Consider clearing all memory and starting fresh if compromise is suspected:
19
+ openclaw memory clear
20
+
21
+ EOF
22
+
23
+ exit 0
24
+
@@ -0,0 +1,27 @@
1
+ #!/bin/bash
2
+ # CHECK 4 (new / MEM-004): Non-whitelisted URLs in memory
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. Review the flagged memory files and inspect the suspicious URLs (check logs above)
12
+
13
+ 2. If the URL is malicious, delete the memory entry:
14
+ openclaw memory clear
15
+
16
+ 3. If the domain is legitimate and should be allowed, add it to the egress allowlist:
17
+ openclaw config set egress.allowlist '["api.openai.com","api.anthropic.com","<your-domain>"]'
18
+
19
+ 4. Review which skill or conversation introduced this URL into memory.
20
+
21
+ 5. Check network logs for any outbound connections to the flagged domain:
22
+ grep "<suspicious-domain>" ~/.openclaw/logs/*.log
23
+
24
+ EOF
25
+
26
+ exit 0
27
+
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+ # CHECK 5 (new / MEM-005): Memory file permissions
3
+ # Usage: ./check_5.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. Fix memory file permissions:
12
+ chmod 600 <memory-file-path>
13
+
14
+ 2. Or fix all memory files at once:
15
+ find ~/.openclaw/workspace/memory -type f -exec chmod 600 {} \;
16
+
17
+ EOF
18
+
19
+ exit 0
20
+