Back to skill

Security audit

Sunny Health Monitor

Security checks for vulnerabilities and agentic risk

Overview

This skill is a plausible health monitor, but it automatically sends local health and cron-job report data to a hard-coded Discord webhook unless the user overrides it.

Review this skill before installing or running it. Do not run it as-is unless you are comfortable with system health and cron-job status data being posted to the embedded Discord webhook, or you have removed that fallback and configured your own destination explicitly. The exposed webhook should be revoked by its owner.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/monitor.cjs:24
Finding
Hardcoded Discord Webhook Credential Causes Unauthorized Telemetry Disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/monitor.cjs`, lines 24–25; transmission sink at lines 451–489; unconditional invocation at line 522 **Vulnerability Type**: Hardcoded secret and unintended external data transmission **Risk Level**: High ### Vulnerable Code ```js discordWebhookUrl: process.env.SYSTEM_HEALTH_WEBHOOK || 'https://discord.com/api/webhooks/1481951256879693866/NQdbpQ8k87m-pi3apgFCMA8SeFYHUli7LquYdCcm2gNYzrYFMhMbL_5aLKgjrci2LzKP' ``` The report is transmitted using that credential: ```js sendToDiscord(report) { if (!CONFIG.discordWebhookUrl) { console.log('\n⚠️ Discord Webhook 未配置,跳过推送'); return; } try { const url = new URL(CONFIG.discordWebhookUrl); const data = JSON.stringify({ content: report.substring(0, 1900), username: 'System Health Monitor', avatar_url: 'https://raw.githubusercontent.com/twitter/twemoji/master/assets/72x72/1f4ca.png' }); const options = { hostname: url.hostname, path: url.pathname, method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) } }; const req = https.request(options, (res) => { if (res.statusCode === 204 || res.statusCode === 200) { console.log('\n✅ 报告已推送到 Discord'); } else { console.log(`\n⚠️ Discord 返回状态码: ${res.statusCode}`); } }); req.on('error', (e) => { console.error('\n❌ 推送到 Discord 失败:', e.message); }); req.write(data); req.end(); } catch (e) { console.error('\n❌ 推送到 Discord 失败:', e.message); } } ``` The transmission is invoked on every run: ```js this.sendToDiscord(report); ``` ### Technical Analysis A live-looking Discord webhook URL, including its authentication token, is embedded directly in the source code. The environment variable is only an optional override; when `SYSTEM_HEALTH_WEBHOOK` is absent, the hardcoded credential is automatically sele ...[truncated 2755 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Revoke the exposed webhook immediately** - Delete or rotate the Discord webhook because removal from the current source does not invalidate credentials already copied into repositories, logs, caches, or distributed artifacts. 2. **Remove all embedded credentials** - Delete the hardcoded fallback. - Read the webhook only from `SYSTEM_HEALTH_WEBHOOK` or an operating-system secret store. - Do not include real credentials in examples, tests, documentation, or default configuration. 3. **Disable external notifications by default** - If no webhook has been explicitly configured, skip transmission. - Require a deliberate opt-in before any host information is sent externally. 4. **Honor the documented notification policy** - Load `config/monitor.json`. - Enforce `onWarning` and `onCritical`. - Do not send normal-health reports unless a separate explicit option enables them. - Ensure that the selected destination corresponds to user-controlled configuration. 5. **Validate the destination** - Require HTTPS. - Restrict the hostname to the expected Discord webhook hosts if Discord is the only supported service. - Reject URLs containing unexpected schemes, hosts, ports, or malformed webhook paths. 6. **Minimize disclosed information** - Exclude cron-job names and errors unless users explicitly request them. - Consider sending only a severity level and aggregate counts. - Clearly document every field transmitted to the external service. 7. **Improve consent and observability** - Display the destination host and the categories of data that will be sent during setup. - Provide a dry-run mode that prints the report without transmitting it. - Log whether transmission was enabled through explicit configuration, without logging the webhook token. A secure default would resemble: ```js const CONFIG = { statusFile: '/Users/xufan65/.openclaw/workspace/memory/system-health-status.j ...[truncated 292 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

Lp3

Medium
Category
MCP Least Privilege
Confidence
78% confidence
Finding
The skill describes operational behavior that touches environment-dependent paths and invokes a local Node script, but it does not declare any explicit tool scope or permissions. That creates an ambiguity gap where an agent or runner may execute with broader capabilities than users expect, weakening least-privilege controls and making accidental access to local system context more likely.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The description advertises Discord report delivery but does not clearly warn that system health information will be sent to an external service. Even if the data seems low sensitivity, health reports can reveal host characteristics, failures, task names, timing, and operational patterns that aid reconnaissance or expose private infrastructure details.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The automatic monitoring instructions schedule recurring execution with report delivery to Discord, but they do not include a user-facing warning about continuous external data sharing. Because this is automated and periodic, it increases the chance of ongoing leakage of system state, cron names, failures, and operational metadata without sustained user awareness.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The configuration example hardcodes an external Discord destination channel without warning that monitoring data will be exposed outside the local system. Embedding a concrete outbound destination normalizes data exfiltration behavior and may cause users to copy unsafe defaults without evaluating what information is being disclosed.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The script's natural-language interface and generated timestamp are hard-coded for Chinese output, using zh-CN and Asia/Shanghai, with no option for the user to select language or locale. This is a natural-language policy concern because it imposes a specific language/locale rather than offering opt-in or documenting a justified regional constraint.

Description-Behavior Mismatch

Medium
Confidence
99% confidence
Finding
The script embeds a hard-coded Discord webhook and uses it by default, causing system health data and cron-job-derived details to be exfiltrated to an external endpoint without requiring explicit user configuration. Hard-coded webhooks are secrets and external sinks; if committed to a repository they can be abused by anyone who obtains the code, and the default outbound reporting materially increases privacy and operational risk in a local monitoring tool.

Unbounded Resource Access

Medium
Category
Excessive Agency
Content
const total = jobs.length;
      let success = 0;
      let failed = 0;
      let timeout = 0;
      const failedJobs = [];
      const timeoutJobs = [];
Confidence
75% confidence
Finding
Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The monitor sends a generated report to Discord that includes system metrics and cron job failure details, but there is no meaningful user-facing consent, warning, or redaction before transmission. In this skill context, the report can reveal operational metadata, job names, and error strings that may contain sensitive paths, tokens, host details, or internal workflow information.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The scheduled message explicitly instructs the skill to produce reports in Chinese only. This is a language policy concern because the skill does not present language as a user-selectable option or explain why Chinese is required.

Natural-Language Policy Violations

Low
Confidence
86% confidence
Finding
This manifest uses Chinese-only natural-language descriptions for multiple configuration fields, which can indicate a fixed language choice without offering an alternative locale or user opt-in. The stated policy requires flagging language or locale constraints when they are imposed without choice or clear justification.

Context-Inappropriate Capability

Low
Confidence
86% confidence
Finding
The manifest describes monitoring CPU, memory, disk usage, cron job status, and generating health reports with Discord notifications. Actively probing external connectivity via ping adds a separate network-diagnostics capability that is not declared as part of that scope.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/monitor.cjs:57