Back to skill

Security audit

Notice Monitor

Security checks for vulnerabilities and agentic risk

Overview

This announcement monitor has a coherent purpose, but it can run shell commands from scraped or configured text and includes a default external DingTalk recipient, so it needs review before installation.

Review this skill carefully before installing. Replace all example notification targets with your own, run only with trusted HTTPS URLs, avoid enabling cron until notification delivery is verified, and prefer a fixed version that removes shell-based message sending and runs Chromium with sandboxing enabled.

Vulnerability Patterns
  • 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
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
src/monitor.js:49
Finding
OS Command Injection in DingTalk Notification Handling<![CDATA[ ## Vulnerability Details **File Location**: `src/monitor.js`, lines 49–60 **Vulnerability Type**: OS command injection through shell interpolation **Risk Level**: Critical ### Vulnerable Code ```js class Notifier { static async send(config, message) { if (config.type === 'dingtalk') { try { const { execSync } = require('child_process'); execSync(`openclaw message send --target "${config.target}" --message "${message.replace(/"/g, '\\"')}"`, { stdio: 'pipe' }); console.log('✅ 消息已发送'); } catch (e) { console.error('❌ 发送失败:', e.message); console.log(message); } } else { console.log(message); } } } ``` ### Technical Analysis The notification target and generated report are interpolated into a command string passed to `child_process.execSync()`. This API executes the string through a system shell. Escaping only double quotation marks in `message` is insufficient. Shell constructs such as command substitutions using `$(...)` or backticks remain active inside double-quoted shell arguments. The `config.target` value is not escaped at all. The report includes remotely sourced notice titles, areas, and dates extracted from the monitored page in `src/monitor.js` lines 123–134. Consequently, this vulnerability crosses two separate trust boundaries: 1. A malicious or compromised configuration can inject commands through `notify.target`. 2. A malicious or compromised monitored website can inject shell syntax into scraped notice content. For example, a matching notice title containing `$(malicious-command)` would be included in the generated report and evaluated by the shell when the notification is sent. ### Attack Path 1. An attacker controls or compromises a website monitored by the Skill. 2. The attacker publishes a table row whose title contains one of the configured keywords and a shell substitu ...[truncated 1306 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not construct a shell command from notification data. Invoke OpenClaw directly with an argument array and disable shell processing: ```js const { execFileSync } = require('child_process'); execFileSync( 'openclaw', [ 'message', 'send', '--target', config.target, '--message', message ], { stdio: 'pipe', shell: false } ); ``` Additional hardening should include: 1. Validate `config.target` against the exact DingTalk identifier format expected by OpenClaw. 2. Reject targets containing control characters, shell metacharacters, or unexpected whitespace. 3. Apply reasonable length limits to titles, areas, dates, task names, and complete reports. 4. Treat all scraped page content as untrusted, even when monitoring a government domain. 5. Prefer a direct OpenClaw API or SDK over invoking a command-line process. 6. Add regression tests containing `$()`, backticks, quotes, newlines, semicolons, and other shell metacharacters. 7. Run the Skill under a dedicated low-privilege operating-system account to limit damage if another injection flaw is introduced. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
src/monitor.js:72
Finding
Chromium Sandbox Disabled While Rendering Arbitrary Websites<![CDATA[ ## Vulnerability Details **File Location**: `src/monitor.js`, lines 72–77 **Vulnerability Type**: Removal of browser isolation for untrusted web content **Risk Level**: High ### Vulnerable Code ```js browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-gpu'] }); ``` ### Technical Analysis The Skill advertises support for monitoring arbitrary URLs and loads each configured URL in Chromium. However, it explicitly supplies both `--no-sandbox` and `--disable-setuid-sandbox`. The Chromium sandbox is a principal security boundary between untrusted renderer content and the host operating system. Disabling it is not required for the declared announcement-filtering functionality and exceeds minimum privilege requirements. It substantially increases the consequences of a Chromium renderer vulnerability because hostile page content is processed without normal process isolation. This does not independently prove that every visited page can execute native host code. Exploitation requires a browser vulnerability or another browser-level compromise. Nevertheless, removing the sandbox creates an unnecessary and security-critical exposure when the application is intentionally designed to visit arbitrary or potentially compromised websites. ### Attack Path 1. A user configures an attacker-controlled website, or a legitimate monitored website is compromised. 2. The Skill opens that site using Puppeteer. 3. Chromium processes attacker-controlled HTML, JavaScript, media, and related web resources. 4. The attacker exploits a vulnerability in the Chromium renderer or a related browser component. 5. Because Chromium was launched without its normal sandbox protections, the exploit has a more direct path to the privileges and resources available to the browser process. 6. The attacker accesses or modifies host resources available to the Skill's operating-system account. ### ...[truncated 632 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--no-sandbox` and `--disable-setuid-sandbox` and run Chromium with its supported sandbox enabled: ```js browser = await puppeteer.launch({ headless: 'new', args: ['--disable-dev-shm-usage', '--disable-gpu'] }); ``` 2. Run the Skill as a dedicated, unprivileged operating-system user. 3. If the deployment environment cannot support Chromium sandboxing, place the entire browser workload in a hardened container or virtual machine with: - A read-only root filesystem. - No host filesystem mounts except a narrowly scoped working directory. - Dropped Linux capabilities. - `no-new-privileges`. - Seccomp and AppArmor or SELinux restrictions. - Strict CPU, memory, and process limits. 4. Restrict configured URLs to `https:` and consider an explicit domain allowlist. 5. Block access to localhost, private address ranges, link-local addresses, and cloud metadata endpoints unless explicitly required. 6. Keep Puppeteer and its bundled Chromium version current and regularly review security advisories. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
configs/default.yaml:28
Finding
Hardcoded DingTalk Recipient Causes Unintended Third-Party Disclosure<![CDATA[ ## Vulnerability Details **File Location**: `configs/default.yaml`, lines 28–31 **Additional Locations**: `configs/examples/hlj-edu.yaml:32–35`, `README.md:98,110,122`, and `SKILL.md:47,59,132,150,168` **Vulnerability Type**: Unsafe hardcoded outbound notification destination **Risk Level**: Medium ### Vulnerable Code ```yaml notify: type: dingtalk target: "01254349410626385789" ``` ### Technical Analysis The active default configuration contains a fixed, real-looking DingTalk recipient rather than a clearly invalid placeholder. The documented installation process instructs users to copy this default file into their workspace and then run the Skill. If a user follows the documented workflow without replacing the value, reports are sent through the user's OpenClaw messaging context to the embedded recipient. The same identifier appears repeatedly in the documentation and in the active Heilongjiang education example, making accidental reuse more likely. A default external recipient is not necessary for website monitoring and violates secure-by-default and least-privilege principles. Notification delivery should require the user to explicitly configure and confirm a destination. ### Attack Path 1. A user copies `configs/default.yaml` as instructed by the project documentation. 2. The user does not notice or replace the embedded DingTalk target. 3. The Skill monitors the configured website and finds a matching new notice. 4. `Notifier.send()` invokes `openclaw message send` using the hardcoded target. 5. The report is delivered to the embedded recipient using the user's configured OpenClaw messaging authority. ### Impact Assessment The recipient may receive information without the user's informed consent, including: - Monitored task names. - Selected industries, institutions, and keywords inferred from reports. - Announcement titles, areas, and dates. - Operational timing indicating when monitoring jobs run. - Any future sensitive content ...[truncated 298 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace all fixed recipient identifiers with an unmistakable placeholder: ```yaml notify: type: dingtalk target: "YOUR_DINGTALK_ID" ``` 2. Refuse to send when the target is absent, unchanged from the placeholder, or invalid. 3. Require explicit recipient configuration before the first non-dry-run execution. 4. Display the resolved recipient and request confirmation during initial setup. 5. Remove the fixed identifier from all examples and documentation. 6. Add a configuration schema that validates notification type and destination. 7. Consider making dry-run behavior the default until notification setup has been explicitly confirmed. 8. Document exactly what report data will be transmitted and through which OpenClaw messaging account. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (33)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### 清除缓存
```bash
rm ~/.openclaw/workspace/state/pushed-ids-*.json
```

---
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### 清除缓存
```bash
rm ~/.openclaw/workspace/state/pushed-ids-*.json
```

---
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Known Vulnerable Dependency: basic-ftp==5.2.0 — 4 advisory(ies): GHSA-6v7q-wjvx-w8wg (basic-ftp: Incomplete CRLF Injection Protection Allows Arbitrary FTP Command Exe); CVE-2026-39983 (basic-ftp has FTP Command Injection via CRLF); CVE-2026-41324 (basic-ftp vulnerable to denial of service via unbounded memory consumption in Cl) +1 more

High
Category
Supply Chain
Confidence
84% confidence
Finding
basic-ftp 5.2.0 is present transitively via get-uri/proxy tooling and has reported command-injection and DoS issues. Even though this skill is not obviously an FTP client from the lockfile alone, vulnerable packages in the dependency tree can become reachable when proxy/PAC/URI handling paths are exercised, especially in automation tooling like Puppeteer.

Known Vulnerable Dependency: extract-zip==2.0.1 — 2 advisory(ies): CVE-2026-19693 (extract-zip allows arbitrary file writes through symlink archive entries); CVE-2026-56876 (extract-zip unvalidated symlink path traversal)

High
Category
Supply Chain
Confidence
90% confidence
Finding
extract-zip 2.0.1 has advisories for symlink-based arbitrary write/path traversal during archive extraction. In this dependency tree it is pulled in by @puppeteer/browsers, which increases relevance because browser automation tools often download and unpack browser binaries automatically, making archive extraction a realistic code path.

Known Vulnerable Dependency: ip-address==10.1.0 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
80% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Known Vulnerable Dependency: js-yaml==4.1.1 — 4 advisory(ies): CVE-2026-84375 (js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources); CVE-2026-59869 (js-yaml: YAML merge-key chains can force quadratic CPU consumption); GHSA-5p4m-2wfm-xmqj (JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026) +1 more

High
Category
Supply Chain
Confidence
80% confidence
Finding
js-yaml 4.1.1 has multiple CPU-exhaustion advisories related to parsing malicious YAML structures. Because the project explicitly depends on yaml and also includes js-yaml transitively through cosmiconfig, configuration parsing is a plausible code path, so hostile YAML input could trigger denial of service if untrusted config files are processed.

Known Vulnerable Dependency: tar-fs==3.0.4 — 3 advisory(ies): CVE-2025-48387 (tar-fs can extract outside the specified dir with a specific tarball); CVE-2024-12905 (tar-fs Vulnerable to Link Following and Path Traversal via Extracting a Crafted ); CVE-2025-59343 (tar-fs has a symlink validation bypass if destination directory is predictable w)

High
Category
Supply Chain
Confidence
92% confidence
Finding
tar-fs 3.0.4 has path traversal and symlink/link-following extraction issues. It is included under @puppeteer/browsers, making it meaningfully reachable in workflows that download and unpack browser artifacts; a crafted archive could write outside the intended directory or abuse predictable extraction targets.

Known Vulnerable Dependency: ws==8.16.0 — 3 advisory(ies): CVE-2024-37890 (ws affected by a DoS when handling a request with many HTTP headers); CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
88% confidence
Finding
ws 8.16.0 has multiple denial-of-service and memory-safety advisories. Since ws is a direct Puppeteer dependency used for DevTools/browser communication, it is more likely to be exercised than many other transitive packages; if exposed to malicious or intermediary-controlled websocket traffic, the skill could crash or leak memory.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The README documents a webhook notification mode that posts monitored notice content to an arbitrary external URL, but it does not include any warning about transmitting potentially sensitive monitoring results or metadata off-system. For markdown files, this falls under missing user warnings about behaviors that could affect privacy or system integrity.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The webhook example encourages sending monitored data and an Authorization bearer token to an external endpoint without any warning about secret handling, TLS validation, endpoint trust, or data exposure. In a monitoring skill that routinely forwards collected notices, this can lead to accidental credential leakage or unintended exfiltration to third-party services.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The description and author fields are written only in Chinese, with no indication that the skill is intended exclusively for Chinese-speaking users or that language selection is configurable. This can violate a language/locale policy when skills are expected to offer user choice or clearly document justified locale constraints.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The notifier builds a shell command by interpolating untrusted configuration data (`config.target`) and message content into `execSync(...)`. Although double quotes in the message are escaped, shell metacharacters such as `$()`, backticks, and quote-breaking sequences in `config.target` can still lead to command injection, causing arbitrary command execution under the privileges of the monitoring process.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The report generation hard-codes the 'zh-CN' locale and Chinese-language output strings, which imposes a specific language/locale on users without any opt-in or configuration path. This matches the policy category for language or locale constraints that are not optional or justified.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The skill documentation uses Chinese throughout and does not indicate that the language is optional, user-selectable, or required for a region-specific compliance reason. This can be a language/locale policy issue when a skill effectively forces a specific language without user opt-in.

Missing User Warnings

Low
Confidence
94% confidence
Finding
The troubleshooting section recommends removing `pushed-ids-*.json`, which is a destructive file deletion operation, but it does not warn users that this will erase state and may cause previously sent notices to be pushed again. In markdown documentation, destructive operations should be accompanied by an explicit warning about their impact.

Missing User Warnings

Low
Confidence
81% confidence
Finding
The skill description repeatedly documents outbound DingTalk notifications using explicit target identifiers, but does not disclose that matched announcement data will be pushed to external messaging platforms. For a markdown skill description, this is a missing user warning about data sharing and privacy impact.

Intent-Code Divergence

Low
Confidence
87% confidence
Finding
The notification parameter table documents `notify` as supporting only `dingtalk / wechat / email`, but later the same file provides a concrete `webhook` notification configuration example. This is an active contradiction in the skill's documentation about what notification modes the skill supports, which can mislead users about the actual behavior and scope.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The manifest description is written entirely in Chinese, which indicates a language-specific user experience but provides no opt-in, alternative language, or justification for restricting the skill to that locale. The policy requires flagging language or locale constraints unless the skill explicitly offers a choice or clearly documents a justified regional scope.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
The file’s natural-language content is entirely in Chinese, including comments, task names, and sample keywords, with no indication that the skill is region-specific or that users may choose another language/locale. Under the policy for natural-language violations, this can be treated as forcing a specific language without explicit opt-in or documented justification.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
This manifest contains user-facing natural-language fields entirely in Chinese, including the example title and task name, but does not state that the skill is Chinese-only or offer any language/locale choice. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Vague Triggers

Low
Confidence
86% confidence
Finding
This manifest-style YAML lists many broad keywords such as '教育', '学校', and '培训' without describing matching logic, exclusion conditions, or negative examples. In a skill configuration, that can make invocation or filtering behavior unclear and increase the chance of unintended matches.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
This YAML contains user-facing natural-language labels and comments entirely in Chinese, such as the example title and task name, with no indication that language selection is optional. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Vague Triggers

Low
Confidence
77% confidence
Finding
This JSON manifest identifies the package as "notice-monitor" and exposes a CLI binary, but provides no information about when or how the skill should be invoked, nor any limiting conditions. For manifest files, absence of specific trigger scope or exclusion conditions can make activation semantics ambiguous in downstream tooling or documentation.

Known Vulnerable Dependency: uuid==8.3.2 — 1 advisory(ies): CVE-2026-41907 (uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided)

Low
Category
Supply Chain
Confidence
60% confidence
Finding
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Known Vulnerable Dependency: yaml==2.8.2 — 1 advisory(ies): CVE-2026-33532 (yaml is vulnerable to Stack Overflow via deeply nested YAML collections)

Low
Category
Supply Chain
Confidence
76% confidence
Finding
yaml 2.8.2 is reported vulnerable to stack exhaustion on deeply nested YAML input. Because yaml is a direct dependency, parsing attacker-controlled YAML could cause process crashes, though the likely consequence is denial of service rather than code execution.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/monitor.js:54