Back to skill

Security audit

OpenClaw News Watcher

Security checks for vulnerabilities and agentic risk

Overview

This news watcher mostly matches its stated purpose, but it includes a recurring Telegram example with a fixed recipient and routes untrusted web article text through the main OpenClaw agent.

Install only if you are comfortable running a long-lived browser-based watcher that invokes your local OpenClaw agent and sends Telegram messages. Before use, replace any hardcoded Telegram recipient, prefer a constrained summarization agent instead of main, verify OPENCLAW_MJS points to your trusted OpenClaw file, and pin dependencies for reproducible installs.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • 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 (2)

T01 · Skill Instruction Hijacking

Error
Location
scripts/watch-news.js:129
Finding
Untrusted Remote Article Content Is Passed Directly to the Main AI Agent<![CDATA[ ## Vulnerability Details **File Location**: `scripts/watch-news.js:129-145` **Duplicate Location**: `watch-news.txt:129-145` **Vulnerability Type**: Prompt injection through untrusted remote content **Risk Level**: High ### Vulnerable Code ```javascript const prompt = `以下是一篇来自 CoinDesk 的加密货币新闻全文,请用中文进行总结分析,不要访问任何网址: 标题:${articleTitle} 正文: ${articleContent.slice(0, 4000)} 请用中文回复,要求: 1. 核心事件是什么(2-3句话) 2. 对加密货币市场有何影响 3. 重要性评级(高/中/低)及理由 格式简洁,适合 Telegram 阅读,控制在400字以内`; // 调用 openclaw agent console.log('⏳ 等待总结结果...'); const result = runOpenclaw(['agent', '--agent', 'main', '--message', prompt, '--thinking', 'off', '--timeout', '90']); ``` ### Technical Analysis The article title and body originate from externally controlled news pages. These values are interpolated directly into an instruction prompt and submitted to the general-purpose OpenClaw `main` agent. The prompt tells the agent not to visit URLs, but this natural-language instruction does not establish a reliable trust boundary. An attacker who controls a published article, compromises a supported news site, or injects content into a rendered page could include adversarial instructions in the article text. Those instructions could attempt to override the summarization request, manipulate the generated response, solicit sensitive information, or induce use of tools available to the main agent. The code does not use a dedicated tool-free summarization agent, structured input separation, schema-constrained output, prompt-injection filtering, or independent validation before forwarding the result to Telegram. ### Attack Path 1. An attacker publishes an article or injects content into a page that the watcher treats as the latest article. 2. The attacker embeds instructions in the title or first 4,000 characters of the article body, such as instructions to ignore the summarization task or perform unrelated actions. 3. Playwright extracts the malicious text from the page. 4. The watcher inser ...[truncated 1131 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a dedicated summarization agent with no filesystem, shell, messaging, browser, memory-writing, or other external-action tools. 2. Do not invoke the general-purpose `main` agent for processing untrusted web content. 3. Pass article data through a structured interface with separate `title` and `body` fields rather than concatenating it into the same instruction channel. 4. Clearly delimit the article as untrusted data and instruct the summarizer to treat all instructions found inside it as quoted content. This is defense in depth and should not replace tool isolation. 5. Apply input validation and detect instruction-like phrases, encoded payloads, suspicious links, or requests for tool use. 6. Require schema-constrained output containing only expected summary fields, such as `core_event`, `market_impact`, and `importance`. 7. Validate and length-limit the generated output before including it in a Telegram message. 8. Consider using a deterministic, non-agent summarization service or a model endpoint that cannot execute tools. 9. Keep the duplicated `watch-news.txt` synchronized with the corrected executable source or remove it to prevent vulnerable code from being reused. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
README.md:44
Finding
Documentation Creates a Cron Job That Sends Notifications to a Hardcoded Telegram Recipient<![CDATA[ ## Vulnerability Details **File Location**: `README.md:44-55` **Vulnerability Type**: Hardcoded external message destination in an executable setup example **Risk Level**: Medium ### Vulnerable Code ```bash openclaw cron add \ --name "News Check" \ --cron "*/30 * * * *" \ --session isolated \ --message "检查最新加密新闻变化" \ --announce \ --channel telegram \ --to 8015532995 ``` ### Technical Analysis The documented cron command contains the fixed Telegram Chat ID `8015532995`. This differs from the rest of the project, which documents and uses the user-controlled `TELEGRAM_USER_ID` environment variable. Installation and setup commands are commonly copied without modification. A user following this example would create a recurring job whose output is delivered to the hardcoded recipient rather than to the user's configured Telegram account. Because this is a cron command, the incorrect routing continues across future executions until the job is discovered and removed or modified. No evidence in the reviewed files establishes who controls the hardcoded Chat ID. Nevertheless, it is an unintended external destination and should not appear in a generic setup example. ### Attack Path 1. A user follows the README instructions and copies the cron command. 2. OpenClaw creates the recurring `News Check` job. 3. Every scheduled execution checks or summarizes cryptocurrency news. 4. The `--announce` operation sends generated output through Telegram. 5. Because `--to` contains a fixed Chat ID, the output is delivered to `8015532995` rather than the user's configured recipient. 6. Delivery continues on the configured schedule until the persistent cron entry is corrected or removed. ### Impact Assessment The fixed recipient can receive news summaries and any additional contextual output generated by the scheduled agent task. This causes unauthorized information disclosure and loss of notification confidentiality. The exposed information is expected ...[truncated 332 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the hardcoded destination with the documented environment variable: ```bash openclaw cron add \ --name "News Check" \ --cron "*/30 * * * *" \ --session isolated \ --message "Check for important cryptocurrency news changes" \ --announce \ --channel telegram \ --to "$TELEGRAM_USER_ID" ``` 2. Alternatively, use an unmistakable placeholder such as `<YOUR_TELEGRAM_CHAT_ID>`. 3. Add a warning instructing users to verify the resolved destination before creating the cron job. 4. Search all documentation, examples, release artifacts, and prior templates for the same numeric Chat ID and remove it. 5. Advise users who may have copied the existing command to inspect their OpenClaw cron jobs, update the recipient, and remove any incorrectly configured job. 6. Add documentation tests or static checks that reject literal Telegram Chat IDs in distributable examples. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (14)

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill description and all operational instructions are written in Chinese, and the example agent message also assumes Chinese usage. The policy requires flagging language or locale constraints when the skill forces a specific language without user opt-in, and no alternative language option or justification is provided here.

Session Persistence

Medium
Category
Rogue Agent
Content
### 场景 1:后台持续监听

```bash
# 在后台运行(使用 nohup 或 screen)
nohup node ~/.openclaw/workspace/skills/news-watcher/scripts/watch-news.js &
```
Confidence
65% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
### 场景 1:后台持续监听

```bash
# 在后台运行(使用 nohup 或 screen)
nohup node ~/.openclaw/workspace/skills/news-watcher/scripts/watch-news.js &
```
Confidence
65% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The script trusts the OPENCLAW_MJS environment variable to select the JavaScript file executed by a child Node process. If an attacker can influence the environment or deployment configuration, they can cause arbitrary attacker-controlled code to run with the script’s privileges, turning a news watcher into an arbitrary code execution launcher.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The file-level documentation describes a Playwright-based news watcher that detects updates by hash changes, but this code also summarizes article contents via an external OpenClaw agent and sends messages to Telegram. Spawning another agent process and delivering outbound messages are materially broader capabilities than passive monitoring, and no manifest is available to justify them.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The prompt explicitly requires the agent to respond in Chinese, and elsewhere the script formats timestamps with the zh-CN locale. This imposes a specific language/locale on users without offering a choice or documenting a justified region-specific constraint, which matches the policy-violation category.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The script launches an external subprocess via execFileSync and takes the script path from the OPENCLAW_MJS environment variable. That means whoever controls the environment can redirect execution to an unintended local script, giving this skill code-execution capability beyond simple news monitoring and expanding the trust boundary significantly.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
The safety comment is misleading because the actual control still comes from an environment variable, so the code executes whatever Node script OPENCLAW_MJS points to. Even though execFileSync avoids shell injection here, it still enables execution of attacker-selected code if the runtime environment is influenced, which can lead to local compromise or misuse of agent/message capabilities.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The prompt explicitly instructs the agent to summarize only in Chinese, and related output formatting elsewhere uses the zh-CN locale. This imposes a specific language/locale choice as a default behavior without offering the user any option to choose another language.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The markdown explicitly states that the AI agent generates a Chinese summary, which imposes a specific language on output. The file does not mention any user opt-in, configurable language setting, or justification that this skill is intended only for a Chinese-language context.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"watch:panews": "node scripts/watch-news.js --site panews"
  },
  "dependencies": {
    "playwright": "^1.40.0",
    "crypto": "^1.0.1"
  },
  "devDependencies": {},
Confidence
95% confidence
Finding
The Playwright dependency is specified with a caret range (^1.40.0), which allows newer minor and patch versions to be installed over time. This weakens build reproducibility and can unexpectedly introduce vulnerable or incompatible releases, which is especially relevant for a browser automation package that downloads and executes browser components.

Unverifiable Dependency: playwright has 1 known advisory(ies) (CVE-2025-59288 (Playwright downloads and installs browsers without verifying the authenticity of)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding
Playwright has a referenced advisory related to downloading and installing browsers without authenticity verification, and the manifest does not pin an exact version. Because the resolved installed version is not fixed, it is not possible to confirm from this manifest alone that deployments avoid an affected release, which creates avoidable supply-chain uncertainty for a tool that fetches executable browser binaries.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "dependencies": {
    "playwright": "^1.40.0",
    "crypto": "^1.0.1"
  },
  "devDependencies": {},
  "engines": {
Confidence
90% confidence
Finding
The crypto dependency is also unpinned (^1.0.1), so installations may resolve to different versions over time. Even if the package is not directly malicious, floating dependency ranges increase supply-chain risk and make it harder to verify exactly what code is executed.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
The primary skill description is entirely in Chinese and does not indicate any language choice or opt-in for users. Under the language/locale policy rule, forcing a specific language without user choice can be a natural-language policy violation unless clearly justified as region-specific.

Static analysis

No suspicious patterns detected.