Back to skill

Security audit

Botlearn Doctor@1.0.2

Security checks for vulnerabilities and agentic risk

Overview

This is a plausible OpenClaw health-check skill, but it over-collects sensitive local data and includes unsafe remediation and report-delivery paths.

Review carefully before installing. Prefer removing curl-to-shell fixes, removing --force from install recommendations, disabling external report delivery and browser auto-open unless explicitly needed, and changing collection to emit only redacted metrics rather than raw config or identity-file contents.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (8)

T03 · Remote Payload Retrieval and Execution

Error
Location
check_skills.md:69
Finding
Remote installer is recommended through an unauthenticated curl-to-shell pipeline<![CDATA[ ## Vulnerability Details **File Location**: `check_skills.md:69` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```markdown **Fix (clawhub missing):** `npm install -g clawhub` or `curl -fsSL https://clawhub.io/install | bash` ``` ### Technical Analysis The recommended command downloads a mutable remote response and immediately executes it with the current user's privileges. There is no version pinning, checksum verification, signature validation, or opportunity to inspect the script before execution. Although the skill's safety gate requires user confirmation before state-changing fixes, confirmation does not make the retrieved payload trustworthy. The effective code can change after this skill package has been reviewed. Compromise of `clawhub.io`, its CDN, DNS resolution, TLS termination, or the installer publication process could result in arbitrary code execution. Installing the CLI may be relevant to skill-management functionality, but direct remote execution is not the minimum privilege or safest installation method. The documented `npm install -g clawhub` alternative also lacks version pinning and provenance verification, although it is less opaque than the pipeline. A similar unsafe recommendation appears at `check_hardware.md:73`: ```markdown **Fix (linux):** `curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo bash -` ``` That variant is more severe because the retrieved payload is passed to a privileged shell. ### Attack Path 1. A health check determines that `clawhub` or a supported Node.js version is missing. 2. The agent presents the documented curl-to-shell command as a remediation. 3. The user approves the proposed fix. 4. The shell retrieves the installer at execution time. 5. A compromised or malicious upstream response supplies arbitrary shell commands. 6. Those commands run as the invoking user, or as root in the `sudo bash` variant. ### Impact Assessment The ...[truncated 315 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove all `curl | bash` and `curl | sudo bash` recommendations. - Prefer a documented package-manager installation from a trusted repository. - Pin an exact package or installer version. - Download installers to a file before execution and verify a publisher signature or a pinned SHA-256 digest. - Display the source, version, digest, and exact local command before requesting confirmation. - Never execute downloaded content directly as root. Separate repository setup from package installation and minimize privileged operations. - For npm installation, use a pinned version such as `npm install -g clawhub@<reviewed-version>` and verify package provenance and integrity metadata. ]]>

T01 · Skill Instruction Hijacking

Error
Location
check_skills.md:190
Finding
Skill instructions declare an entire vendor namespace trusted and bypass installation risk prompts<![CDATA[ ## Vulnerability Details **File Location**: `check_skills.md:190-194` **Vulnerability Type**: Safety-control bypass through skill instructions **Risk Level**: High ### Vulnerable Code ```markdown ```bash clawhub install @botlearn/<skill-name> --force ``` `--force` skips interactive risk prompts for trusted botlearn skills. ``` The broader policy at `check_skills.md:127-166` asserts that all `@botlearn/*` skills are trusted, penalizes systems that do not have them installed, and recommends missing packages. `SKILL.md:299-310` contains the same scoring and `--force` recommendation. ### Technical Analysis Package trust is inferred solely from a namespace and promotional assertions rather than from a cryptographic identity, reviewed version, signature, or package-specific assessment. The `--force` option deliberately suppresses interactive risk prompts that are intended to warn about dangerous capabilities or package behavior. The health score is also reduced when vendor-specific packages are absent. This changes the skill's objective from neutral system health assessment to encouraging installation from one ecosystem. When loaded by an agent, these instructions can bias the agent toward recommending additional code and bypassing the installer’s safety checks. The general Phase 4 confirmation requirement reduces automatic exploitation, but it does not restore the skipped package-level review. A user is being asked to approve an installation after the skill has already labeled the namespace trusted. ### Attack Path 1. An attacker publishes or compromises a package under a name returned by the `botlearn` registry search. 2. The collection script reports the package as missing. 3. The scoring policy penalizes the installation for not having the package. 4. The agent recommends `clawhub install ... --force`. 5. After user confirmation, `--force` suppresses the package manager’s risk prompts. 6. The package installs and executes with the privileges ava ...[truncated 385 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `--force` from all generated installation commands. - Do not classify packages as trusted solely because of their namespace. - Eliminate vendor-specific package counts from the health score unless they are explicit, user-selected requirements. - Require package-specific provenance, signature, version, publisher, capability, and source review. - Pin reviewed package versions and show requested permissions before installation. - Preserve all installer risk prompts and require separate confirmation for each package. - Clearly distinguish optional recommendations from actual health or security defects. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
data_collect.md:74
Finding
Raw OpenClaw configuration is copied into agent context without secret redaction<![CDATA[ ## Vulnerability Details **File Location**: `data_collect.md:74-80` **Vulnerability Type**: Excessive access to sensitive configuration **Risk Level**: High ### Vulnerable Code ```markdown ### 2.1 Main Config File ```bash cat "${OPENCLAW_HOME:-$HOME/.openclaw}/openclaw.json" 2>/dev/null # Fallback: also try $HOME/.openclaw/config/openclaw.json ``` Store raw JSON content as `DATA.openclaw_json`. Purpose: cross-validate against `DATA.config` script output; catch any unusual overrides. ``` ### Technical Analysis The protocol explicitly places the complete raw configuration in the model's working context. OpenClaw configuration can contain authentication tokens, webhook URLs, channel credentials, or other sensitive connection data. Unlike the security scanner, which emits only a secret type, path, line number, and redacted placeholder, this direct-read path has no redaction step. The stated purpose is structural cross-validation. That purpose can be achieved locally by parsing the file and returning only selected non-secret fields, hashes, presence indicators, or mismatch records. Giving the agent the complete file therefore exceeds the minimum data access necessary for the declared health-check function. The later instruction not to print credential values only controls final output; it does not prevent secret values from entering model context, traces, diagnostics, or intermediate storage. ### Attack Path 1. A user stores a gateway token, webhook credential, or another secret in `openclaw.json`. 2. A routine health check executes the direct `cat` instruction. 3. The complete file is stored as `DATA.openclaw_json`. 4. The credential enters agent context before any redaction is applied. 5. The value may subsequently be exposed through model telemetry, debugging, prompt injection in another collected file, or an accidental report-generation path. ### Impact Assessment Exposure may compromise gateway authentication, messaging integrations, webhook ...[truncated 182 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never place raw configuration in model context. - Parse configuration in a local script and emit an allowlisted schema containing only fields needed for scoring. - Replace credentials and webhook URLs with booleans such as `configured: true`, or with non-reversible fingerprints where comparison is necessary. - Apply recursive key-based and value-pattern redaction before serialization. - Reject unexpected sensitive fields rather than passing them through. - Add automated tests using representative API keys, JWTs, URLs with embedded credentials, private keys, and passwords to ensure no secret reaches output. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
data_collect.md:149
Finding
Personal workspace identity files are ingested in full when only structural metrics are needed<![CDATA[ ## Vulnerability Details **File Location**: `data_collect.md:149-177` **Vulnerability Type**: Excessive collection of personal and agent-identity data **Risk Level**: Medium ### Vulnerable Code ```markdown ### 2.7 Workspace Identity Files Read the agent's core identity and configuration files from the workspace directory. These define who the agent is, who the user is, and what tools the agent has access to. ```bash WORKSPACE_DIR="${OPENCLAW_HOME:-$HOME/.openclaw}/workspace" for file in agent.md soul.md user.md identity.md tool.md; do echo "=== $file ===" cat "$WORKSPACE_DIR/$file" 2>/dev/null || echo "[MISSING]" echo "=== END ===" done ``` Store as `DATA.workspace_identity`: ```json { "agent_md": { "exists": true, "word_count": 350, "content": "..." }, "soul_md": { "exists": true, "word_count": 120, "content": "..." }, "user_md": { "exists": false, "word_count": 0, "content": null }, "identity_md": { "exists": true, "word_count": 85, "content": "..." }, "tool_md": { "exists": false, "word_count": 0, "content": null } } ``` ``` ### Technical Analysis The scoring logic primarily needs file existence, word counts, section presence, and limited personalization indicators. Nevertheless, the collection protocol reads and stores the complete contents of `user.md`, `soul.md`, `identity.md`, and tool/agent files in model context. These files may contain personally identifying information, behavioral rules, private operational details, tool descriptions, or sensitive user preferences. The instruction not to echo the raw content in the final report does not prevent the data from being processed or retained upstream. Full-content ingestion is therefore broader than necessary for health scoring and creates an avoidable privacy boundary violation. ### Attack Path 1. A user records personal information or confidential instructions in workspace identity files. 2. A general health check reads every file in full. 3. Th ...[truncated 606 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Compute existence, word count, headings, and allowlisted feature flags locally. - Return only aggregate metrics to the agent. - Do not include a `content` property in `DATA.workspace_identity`. - If content inspection is essential, obtain explicit consent and process only narrowly selected sections. - Treat workspace files as untrusted input and prevent their contents from becoming executable agent instructions. - Add size limits and robust secret/PII detection before any optional content processing. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/deliver-report.sh:133
Finding
Report and webhook data are interpolated into shell commands with inadequate escaping<![CDATA[ ## Vulnerability Details **File Location**: `scripts/deliver-report.sh:133-149` **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```javascript const webhook = config.channels?.slack?.webhook_url; if (!webhook) { results.push({ channel: "slack", status: "skipped", reason: "No webhook_url" }); break; } const issues = (report.issues || []).slice(0, 5); const issuesMd = issues.map((i, idx) => (idx+1) + ". " + i.severity.toUpperCase() + " [" + i.id + "] " + i.msg).join("\n"); const payload = JSON.stringify({ blocks: [ { type: "header", text: { type: "plain_text", text: "🏥 OpenClaw Health Report" } }, { type: "section", fields: [ { type: "mrkdwn", text: "*Score:* " + report.overall_score + "/100 " + statusEmoji(report.overall_score) }, { type: "mrkdwn", text: "*Status:* " + report.overall_status } ]}, { type: "section", text: { type: "mrkdwn", text: issuesMd || "No issues found" } } ] }); const safe = redactSecrets(payload); execSync("curl -sS -X POST -H \"Content-Type: application/json\" -d " + JSON.stringify(safe) + " " + JSON.stringify(webhook), { timeout: 10000 }); ``` Equivalent command construction is used for DingTalk at lines 154-166, Feishu at lines 172-191, and Discord at lines 197-216. ### Technical Analysis `child_process.execSync()` invokes a shell. `JSON.stringify()` produces JSON string syntax, not POSIX shell escaping. In particular, strings are generally surrounded by double quotes, inside which shells still process command substitutions such as `$(command)` and backticks. Both the webhook URL and portions of the payload can originate from external or locally mutable data. Slack and DingTalk payloads include report issue messages, which may be derived from logs, configuration, package metadata, or diagnostic output. Secret redaction does not sanitize shell metacharacters. Consequently, a crafted value such as `$(touch /tmp/report-pwned)` can be evaluated by the shel ...[truncated 918 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace `execSync()` string commands with `execFileSync()` or `spawnSync()` and an argument array: ```javascript execFileSync("curl", [ "-sS", "-X", "POST", "-H", "Content-Type: application/json", "--data-binary", safe, "--", webhook ], { timeout: 10000 }); ``` - Validate webhook URLs with the `URL` class and allow only `https:` destinations and expected provider hostnames. - Prefer a native HTTPS client instead of invoking `curl`. - Treat all report fields as untrusted data. - Add tests containing `$()`, backticks, quotes, newlines, leading dashes, and shell metacharacters. - Ensure outbound delivery occurs only to explicitly selected, reviewed destinations. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/deliver-report.sh:221
Finding
SMTP host and port configuration permit shell command injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/deliver-report.sh:221-239` **Vulnerability Type**: OS command injection in email delivery **Risk Level**: High ### Vulnerable Code ```javascript const subject = (emailConf.subject_prefix || "[OpenClaw Doctor]") + " Health Report — " + report.overall_score + "/100 " + report.overall_status; const from = emailConf.from || "OpenClaw Doctor <noreply@localhost>"; const htmlContent = htmlFile && fs.existsSync(htmlFile) ? fs.readFileSync(htmlFile, "utf8") : "<p>Score: " + report.overall_score + "/100</p>"; const safeHtml = redactSecrets(htmlContent); const emailPayload = "From: " + from + "\nTo: " + emailConf.to + "\nSubject: " + subject + "\nContent-Type: text/html; charset=UTF-8\n\n" + safeHtml; const tmpFile = "/tmp/doctor-email-" + Date.now() + ".eml"; fs.writeFileSync(tmpFile, emailPayload); try { const host = emailConf.smtp_host || "localhost"; const port = emailConf.smtp_port || 25; execSync("sendmail -t < " + JSON.stringify(tmpFile) + " 2>/dev/null || curl --url smtp://" + host + ":" + port + " --mail-from " + JSON.stringify(from) + " --mail-rcpt " + JSON.stringify(emailConf.to) + " --upload-file " + JSON.stringify(tmpFile), { timeout: 10000 }); results.push({ channel: "email", status: "delivered", to: emailConf.to }); } catch { results.push({ channel: "email", status: "failed", error: "sendmail/smtp delivery failed" }); } try { fs.unlinkSync(tmpFile); } catch {} ``` ### Technical Analysis The `smtp_host` and `smtp_port` values are concatenated directly into an `execSync()` shell command without quoting or validation. Shell separators, substitutions, redirects, and other metacharacters are therefore interpreted as command syntax. The use of `sendmail ... || curl ...` does not mitigate the issue. An attacker can arrange for an injected command to execute in the fallback branch, or can use syntax that changes the structure of the complete command. The message headers are also assembled ...[truncated 857 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not construct SMTP commands through a shell. - Use a maintained SMTP library with TLS and explicit certificate validation. - If `curl` must be retained, invoke it with `execFileSync()` and an argument array. - Validate `smtp_host` as a hostname or IP address and restrict `smtp_port` to an integer from 1 through 65535. - Reject CR and LF characters in `from`, `to`, and subject configuration. - Validate recipient addresses and enforce an explicit recipient allowlist. - Remove the shell `||` fallback and handle fallback logic directly in JavaScript. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/deliver-report.sh:226
Finding
Email reports use a non-exclusive temporary file and plaintext SMTP fallback<![CDATA[ ## Vulnerability Details **File Location**: `scripts/deliver-report.sh:226-239` **Vulnerability Type**: Unsafe temporary-file handling and plaintext transmission **Risk Level**: Medium ### Vulnerable Code ```javascript const htmlContent = htmlFile && fs.existsSync(htmlFile) ? fs.readFileSync(htmlFile, "utf8") : "<p>Score: " + report.overall_score + "/100</p>"; const safeHtml = redactSecrets(htmlContent); const emailPayload = "From: " + from + "\nTo: " + emailConf.to + "\nSubject: " + subject + "\nContent-Type: text/html; charset=UTF-8\n\n" + safeHtml; const tmpFile = "/tmp/doctor-email-" + Date.now() + ".eml"; fs.writeFileSync(tmpFile, emailPayload); try { const host = emailConf.smtp_host || "localhost"; const port = emailConf.smtp_port || 25; execSync("sendmail -t < " + JSON.stringify(tmpFile) + " 2>/dev/null || curl --url smtp://" + host + ":" + port + " --mail-from " + JSON.stringify(from) + " --mail-rcpt " + JSON.stringify(emailConf.to) + " --upload-file " + JSON.stringify(tmpFile), { timeout: 10000 }); results.push({ channel: "email", status: "delivered", to: emailConf.to }); } catch { results.push({ channel: "email", status: "failed", error: "sendmail/smtp delivery failed" }); } try { fs.unlinkSync(tmpFile); } catch {} ``` ### Technical Analysis The report is written into the shared `/tmp` namespace using a timestamp-derived filename. The file is not opened with exclusive creation, symlink protection, or an explicitly restrictive mode. This creates a race in which another local user may predict or discover the path and place a symlink before the write, potentially redirecting the write to another file accessible to the OpenClaw user. File confidentiality also depends on the process umask. The fallback transmits the report using `smtp://` rather than TLS-protected `smtps://` or enforced STARTTLS. Health reports can contain internal paths, software versions, network posture, and security findings. The redaction expression is not a co ...[truncated 853 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Avoid temporary files by passing the message through standard input to a non-shell child process. - If a file is required, use `fs.mkdtemp()` to create a private directory and open the file with `O_CREAT | O_EXCL | O_NOFOLLOW` where supported. - Set permissions explicitly to `0600`. - Clean up the private directory in a `finally` block. - Require TLS with certificate and hostname verification; do not silently fall back to plaintext SMTP. - Treat redaction as defense in depth, not as a substitute for encrypted transport. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/collect-security.sh:257
Finding
OPENCLAW_HOME is concatenated into a shell command in the security scanner<![CDATA[ ## Vulnerability Details **File Location**: `scripts/collect-security.sh:257-269` **Vulnerability Type**: OS command injection through environment-controlled path **Risk Level**: High ### Vulnerable Code ```javascript // Check for tracked secrets try { const tracked = execSync("git ls-files " + HOME + " 2>/dev/null", { encoding: "utf8", timeout: 3000 }); const secretFiles = tracked.split("\n").filter(f => f.endsWith(".key") || f.endsWith(".pem") || f.endsWith(".env") || f.includes("credentials") || f.includes("secret") ); for (const sf of secretFiles) { if (sf.trim()) { result.vcs_sensitive.findings.push({ type: "tracked_secret", file: sf.replace(process.env.HOME, "~"), severity: "critical", msg: "Potentially sensitive file tracked in git" }); } } } catch {} ``` `HOME` is initialized at line 18: ```javascript const HOME = process.env.OPENCLAW_HOME || (process.env.HOME + "/.openclaw"); ``` ### Technical Analysis `OPENCLAW_HOME` is an environment-controlled value and is concatenated into a command executed by a shell. No quoting, argument separation, or path validation is applied. A value containing spaces changes command semantics, while shell separators or substitutions can execute arbitrary commands. Catching the resulting exception does not prevent command execution; it only suppresses evidence after the shell has already processed the malicious value. ### Attack Path 1. An attacker controls the environment used to launch the health check, a wrapper script, or a service definition supplying `OPENCLAW_HOME`. 2. The variable is set to a value containing a shell fragment. 3. The security collection script runs as part of the normal health check. 4. `execSync()` creates a shell command containing the untrusted value. 5. The shell executes the injected command with the health-check user's privileges. ### Impact Assessment The attacker can execute arbitrary commands as the Ope ...[truncated 207 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace the shell command with an argument-based invocation: ```javascript execFileSync("git", ["ls-files", "--", HOME], { encoding: "utf8", timeout: 3000 }); ``` - Canonicalize `OPENCLAW_HOME` with `path.resolve()` and ensure it points to an expected directory. - Reject NUL bytes and unexpected control characters. - Avoid relying on environment variables from untrusted launch contexts. - Add tests using paths containing spaces, quotes, semicolons, substitutions, and leading hyphens. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (74)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
A skill described as an autonomous live health checker but actually requiring an existing report file and launching a local browser introduces undisclosed local file handling and application-launch behavior. Unexpected local file opening can expose sensitive report contents to other local users, browser extensions, sync tooling, or shell integrations and exceeds least-surprise expectations for a diagnostic skill.

Vague Triggers

High
Confidence
97% confidence
Finding
Broad triggers like "diagnose," "doctor," "what's wrong," and "fix my setup" can unintentionally invoke a skill that performs extensive host inspection, file reads, and shell-based data collection. Because the skill has powerful diagnostic behavior and no declared tool scoping, accidental activation materially raises exposure of sensitive environment, config, and log data.

Credential Access

High
Category
Privilege Escalation
Content
| Control UI exposed | `controlUI` on non-loopback | false | — | true | ❌ -25 |
| Critical CVEs | `vulnerabilities` CVSS ≥9 | 0 | — | any | -15 each (max -45) |
| High CVEs | `vulnerabilities` CVSS 7–8.9 | 0 | any | — | -5 each (max -20) |
| Secrets tracked in VCS | `vcs` | clean | .env without .gitignore | tracked in git | -10 / -25 |

**Risk classification** (add after scoring):
- Critical: any ❌ from credential exposure or unauthenticated LAN bind → fix immediately
Confidence
96% confidence
Finding
The skill explicitly directs scanning configs, logs, workspace files, gateway error logs, identity directories, and VCS state for credentials and secret exposure. Even with a stated privacy rule, this is high-risk because a diagnostic skill is being authorized to access secret-bearing locations across the host, and any redaction failure, logging mistake, report export, or browser/display feature could disclose credentials.

Chaining Abuse

High
Category
Tool Misuse
Content
| < 16 | ❌ | -40 | Unsupported — OpenClaw will not run |

**Fix (darwin):** `brew install node` or `nvm install --lts`
**Fix (linux):** `curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo bash -`

---
Confidence
95% confidence
Finding
The shell pipeline chains remote content retrieval directly into privileged execution, reducing opportunities for inspection and making accidental or malicious execution far more likely. In a health-check skill that provides actionable fixes, users may copy-paste the command verbatim, amplifying the danger.

External Script Fetching

High
Category
Supply Chain
Content
| `clawhub_available = true`, `registry_reachable = false` | ⚠️ | -10 — clawhub present but offline |
| `can_install = true` | ✅ | 0 — self-improvement is fully enabled |

**Fix (clawhub missing):** `npm install -g clawhub` or `curl -fsSL https://clawhub.io/install | bash`
**Fix (registry unreachable):** Check internet connectivity; try `clawhub ping`

---
Confidence
98% confidence
Finding
The guidance includes `curl -fsSL https://clawhub.io/install | bash`, which downloads and executes remote code directly in the shell without verification. This is a classic high-risk pattern: if the host, transport, DNS, CDN, or upstream script is compromised, it enables immediate arbitrary code execution on the target system.

Credential Access

High
Category
Privilege Escalation
Content
}

const scanTargets = [
  ...scanDir(HOME + "/config", [".json", ".yaml", ".yml", ".toml", ".env", "*"]),
  ...scanDir(LOG_DIR, [".log", ".txt"]).slice(0, 5) // limit log scan
];
Confidence
81% confidence
Finding
The script reads configuration files and scans them for secrets, which necessarily gives it access to credential material present in those files. Even though values are redacted in output, the broad recursive scan including all file types under the config directory increases exposure risk if the skill is run in environments containing unrelated sensitive files or symlinks.

Credential Access

High
Category
Privilege Escalation
Content
...scanDir(LOG_DIR, [".log", ".txt"]).slice(0, 5) // limit log scan
];

// Also scan .env files in OPENCLAW_HOME
const envFile = HOME + "/.env";
if (fs.existsSync(envFile)) scanTargets.push(envFile);
Confidence
84% confidence
Finding
Explicitly targeting the .env file gives the script access to one of the most common locations for plaintext secrets. Although the intent is defensive and output is redacted, reading credential-bearing files is still sensitive and can become dangerous if the skill is reused, modified, or its results are logged elsewhere.

Credential Access

High
Category
Privilege Escalation
Content
];

// Also scan .env files in OPENCLAW_HOME
const envFile = HOME + "/.env";
if (fs.existsSync(envFile)) scanTargets.push(envFile);

result.credential_exposure.scanned_files = scanTargets.length;
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
];

// Also scan .env files in OPENCLAW_HOME
const envFile = HOME + "/.env";
if (fs.existsSync(envFile)) scanTargets.push(envFile);

result.credential_exposure.scanned_files = scanTargets.length;
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
];

// Also scan .env files in OPENCLAW_HOME
const envFile = HOME + "/.env";
if (fs.existsSync(envFile)) scanTargets.push(envFile);

result.credential_exposure.scanned_files = scanTargets.length;
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/collect-security.sh:48

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/collect-tools.sh:44

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/deliver-report.sh:118