Back to skill

Security audit

Capital Market Report

Security checks for vulnerabilities and agentic risk

Overview

This market-reporting skill is mostly aligned with financial news reporting, but it requires persistent local storage and includes an unsafe automatic report-deletion command that users should review before installing.

Review this skill carefully before installing. It should only be used if you are comfortable with it reading and writing OpenClaw memory/report files, caching fetched news, invoking other local skill scripts, and performing cleanup. The deletion instruction should be corrected or removed before routine use, because it can remove more report history than intended.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:143
Finding
Overbroad Report Cleanup Deletes All Matching Reports<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:143` **Vulnerability Type**: Unsafe destructive file operation **Risk Level**: Medium ```bash rm memory/capital_market_report_*.md ``` ### Technical Analysis The Skill states that only reports older than 24 hours should be removed, but the prescribed command contains no age filter. Shell wildcard expansion causes every matching report in the relative `memory` directory to be deleted, including the report just generated and all reports required for the 24-hour Delta comparison. The relative path also makes the affected directory dependent on the Agent's current working directory. The command runs with the invoking user's privileges and does not require elevated access, but it exceeds the minimum file-deletion scope required by the declared retention policy. ### Attack Path 1. The Agent generates and saves a new capital-market report. 2. The Agent follows the mandatory cleanup instruction in `SKILL.md`. 3. The shell resolves `memory/capital_market_report_*.md` relative to the current working directory. 4. `rm` deletes every matching file without checking modification time. 5. The current report and historical Delta baseline may be irreversibly lost. No external attacker-controlled input is necessary; execution of the documented workflow is sufficient to trigger the issue. ### Impact Assessment The operation can delete all matching report files accessible to the current user in the resolved `memory` directory. It does not grant additional privileges or system-wide access, but it can cause data loss, invalidate report history, and prevent accurate 24-hour Delta analysis. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions Use an absolute, explicitly scoped directory and apply an age condition: ```bash REPORT_DIR="$HOME/.openclaw/workspace-group/memory" find "$REPORT_DIR" -maxdepth 1 -type f \ -name 'capital_market_report_*.md' \ -mmin +1440 \ -delete ``` Additional hardening measures: 1. Verify that `REPORT_DIR` exists and resolves to the expected directory before deletion. 2. Preview the selected files with `-print` before enabling `-delete`. 3. Exclude the newly generated report explicitly if necessary. 4. Avoid making destructive cleanup a prerequisite for publishing the report. 5. Log every deleted path to support recovery and incident investigation. 6. Consider moving expired reports to a quarantine or archive directory instead of immediately deleting them. ]]>

T08 · Insecure Dependencies

Note
Location
scripts/news-processor.py:2
Finding
Runtime Dependencies Are Not Reproducibly Pinned<![CDATA[ ## Vulnerability Details **File Locations**: `scripts/news-processor.py:2-6`; `scripts/generate-report.py:2-5` **Vulnerability Type**: Unpinned third-party runtime dependencies **Risk Level**: Low ```python # /// script # requires-python = ">=3.10" # dependencies = [ # "requests>=2.28.0", # ] # /// ``` ```python # /// script # requires-python = ">=3.10" # dependencies = ["pytz"] # /// ``` ### Technical Analysis The scripts are intended to run through `uv run`, which may resolve and install dependencies at execution time. The `requests` declaration permits any version at or above 2.28.0, while `pytz` has no version constraint. No reviewed lockfile or package hashes are present in the audited project. Consequently, the code executed in the future may differ from the dependency versions used during review. A compromised, malicious, or unexpectedly incompatible future package release or transitive dependency could enter the runtime environment without a corresponding change to the Skill's source files. This is a supply-chain hardening weakness. The audit found no evidence that the named packages are currently malicious, typosquatted, or intentionally selected for exploitation. ### Attack Path 1. A user or Agent invokes one of the scripts through `uv run`. 2. The package manager resolves dependencies allowed by the broad or absent version constraints. 3. A newer or altered package version is downloaded from the configured package registry. 4. Package installation or import executes code that was not part of the reviewed Skill package. 5. Any malicious dependency code executes with the same privileges and environment access as the invoking user. Successful exploitation would require compromise of an accepted package release, dependency source, or package-resolution environment. ### Impact Assessment Dependency code runs with the privileges of the user executing the Skill. A compromised dependency could theoretically access files available to ...[truncated 367 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin each direct dependency to a specifically reviewed version. 2. Generate and commit a `uv.lock` file or equivalent reproducible dependency lock. 3. Require locked execution and reject dependency resolution that would modify the lockfile. 4. Pin transitive dependencies and use package hashes where supported. 5. Review dependency updates before changing pinned versions. 6. Use a trusted, explicitly configured package index. 7. Add automated vulnerability and provenance checks to the dependency-update process. Example declarations: ```python # dependencies = [ # "requests==<reviewed-version>", # ] ``` ```python # dependencies = [ # "pytz==<reviewed-version>", # ] ``` The placeholders should be replaced with versions selected and verified by the project maintainers. ]]>
Vulnerability Patterns
  • 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
  • Rogue AgentSelf-Modification, Session Persistence
Findings (35)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The description promises a sophisticated cross-market anomaly/news reporting system with explicit source governance and verification. The supplied code does something materially simpler and different: it calculates market-open display status, invokes local scripts to get stock index and BTC prices, and formats a static report shell. The 'news' portion is not implemented; it contains placeholders instructing future collection from certain outlets, but no scraping, searching, URL extraction, whitelist enforcement, source diversity, temporal checks, or anti-hallucination safeguards exist in code. Additionally, the outlets listed in the template differ from the declared set (e.g., 36氪/人民网 appear, while Reuters/东方财富/华尔街见闻 are absent). Therefore the declared description does not accurately represent the actual behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The code’s actual purpose is a simple recent-news fetcher for the last 24 hours from three Chinese finance outlets. While these outlets are mentioned within the declared source set, the implementation is far narrower and materially different from the stated skill. The description promises sophisticated report generation across both Chinese and global markets, using additional sources and Brave search, with whitelist enforcement, diversity quotas, signal scanning, temporal verification, and market-isolation controls. None of those behaviors appear in the code. The script merely retrieves and prints news entries; it does not analyze, score, verify, isolate markets, or synthesize anomaly/delta reports. Therefore the declared description does not accurately represent the supplied code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description promises a sophisticated market-anomaly reporting skill with search-based source discovery, whitelist enforcement, diversity constraints, verification guardrails, and strict coverage rules across named Chinese and global media. The supplied code instead performs straightforward scraping of a fixed set of endpoints and RSS feeds, then deduplicates and assigns sentiment via simple keyword matching. It outputs a raw news summary report and counts. While it does cover both Chinese and foreign news and includes source URLs when available, many core declared features are absent, and the actual source set materially differs from the declared one. Therefore the description does not accurately represent the code’s actual behavior.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```

- ⛔ 此步骤不可跳过。未成功存盘则不得输出报告。
- 存盘后立即执行:删除 24 小时前的旧文件 `rm memory/capital_market_report_*.md`(只保留 24h 内的)
- 下一份报告生成时,第一步就是 `ls memory/capital_market_report_*.md` 加载过去 24h 全部已存报告作为 Delta 基线

### 3.1 格式锁
Confidence
98% confidence
Finding
This duplicated finding identifies the same unsafe deletion pattern: a destructive shell command with wildcard expansion and no guardrails. In agentic contexts, parameterized shell deletion is particularly risky because environment differences or future edits can broaden the deletion target unexpectedly.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```

- ⛔ 此步骤不可跳过。未成功存盘则不得输出报告。
- 存盘后立即执行:删除 24 小时前的旧文件 `rm memory/capital_market_report_*.md`(只保留 24h 内的)
- 下一份报告生成时,第一步就是 `ls memory/capital_market_report_*.md` 加载过去 24h 全部已存报告作为 Delta 基线

### 3.1 格式锁
Confidence
98% confidence
Finding
This duplicated finding identifies the same unsafe deletion pattern: a destructive shell command with wildcard expansion and no guardrails. In agentic contexts, parameterized shell deletion is particularly risky because environment differences or future edits can broaden the deletion target unexpectedly.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
cmd = f"uv run {script_path} {' '.join(all_codes)}"
    
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        # 解析输出 - 按顺序匹配
        lines = result.stdout.strip().split('\n')[2:]  # 跳过表头
        data = {}
Confidence
97% confidence
Finding
This is a true tool-parameter abuse issue because a shell command is assembled dynamically and executed through the shell, allowing shell metacharacters, path manipulation, or environmental influence to alter behavior. In this skill context, the command launches another local script from a user-home path, so compromise of that path or future argument expansion could lead to arbitrary local command execution under the agent's privileges.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
cmd = f"uv run {script_path} {symbol}"
    
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        # 解析: "Bitcoin (BTC): $67,947.09"
        line = result.stdout.strip()
        if "$" in line:
Confidence
96% confidence
Finding
The function accepts a symbol parameter and passes it into a shell command string, creating a direct avenue for tool-parameter abuse if the parameter ever becomes user-controlled or indirectly influenced. Because the code executes a local script from a workspace path, successful exploitation could run arbitrary commands or a swapped malicious helper script, making the impact substantial.

External Script Fetching

High
Category
Supply Chain
Content
# 1. 新浪财经 - 要闻(增加数量到30条)
echo "【新浪财经要闻】"
curl -s "https://feed.mix.sina.com.cn/api/roll/get?pageid=153&lid=2509&k=&num=50&r=0.123" 2>/dev/null | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
# 2. 财联社 - 电报(增加数量到30条)
echo "【财联社电报】"
curl -s "https://www.cls.cn/api/telegraph?app=CailianpressWeb&os=web&sv=8.4.6&sign=" 2>/dev/null | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
# 3. 华尔街见闻(增加数量到20条)
echo "【华尔街见闻】"
curl -s "https://api.wallstreetcn.com/apiv1/content/articles?platform=wscn-platform&channel=global&limit=30" 2>/dev/null | python3 -c "
import sys, json
try:
    data = json.load(sys.stdin)
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill invokes shell commands, reads prior reports, writes new reports, and expects network-backed data collection, but it does not declare an explicit tool scope or allowed-tools boundary. That creates an authorization and review gap: an operator may approve a reporting skill without realizing it can access files, persist data, and execute shell actions.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The skill content and output requirements are written to enforce Chinese-language reporting behavior, including Chinese labels and formatting conventions, without indicating that the user may choose another language. This creates a locale policy concern because the skill appears to mandate a specific language by default rather than offering opt-in or documenting a justified regional constraint.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# 文件名格式:capital_market_report_YYYYMMDD_HHMM.md
# 示例输出:
write ~/.openclaw/workspace-group/memory/capital_market_report_20260515_1500.md
```

- ⛔ 此步骤不可跳过。未成功存盘则不得输出报告。
Confidence
88% confidence
Finding
The skill mandates writing reports into persistent local memory, creating a durable record of generated content and source-derived summaries across sessions. Persistent storage can expose sensitive prompts, outputs, or research history to later tasks or users if retention, isolation, and access controls are not clearly bounded.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The documentation instructs deletion of local files as part of normal operation even though file destruction is not necessary to generate a market report. Normalizing cleanup commands in a reporting skill expands its effect on the local environment and can lead to unintended data loss, especially if paths or globbing behave unexpectedly.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
A skill whose core purpose is report generation should not include unrelated destructive filesystem operations. This widens the blast radius of execution and makes it easier for operators or downstream agents to perform harmful actions under the guise of routine report handling.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill directs the agent to delete files automatically without any user-facing warning, review step, or confirmation. Silent destructive actions are dangerous because they can irreversibly remove historical data and are easy to trigger repeatedly in an automated workflow.

Intent-Code Divergence

Medium
Confidence
88% confidence
Finding
The docstring states the generator 'always fetches all data' and later comments repeat that market-time checks are only for display. In reality, the script only fetches stock and Bitcoin data; commodity prices are left as placeholders and news collection is entirely unimplemented, so the documentation overstates what the code actually retrieves.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The file's natural-language description and embedded report content are entirely in Chinese and indicate fixed behavior for generating the report, with no opt-in or language-selection mechanism. The policy requires flagging language or locale constraints when the skill forces a specific language without user choice or a clearly documented regional justification.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
This code constructs a shell command and executes an external script via subprocess.run(..., shell=True), but the only nearby comments describe data retrieval and not the fact that a shell subprocess is being launched. Under the code-file criteria, subprocess execution should have some disclosure such as a clear user-facing log, confirmation, or documented warning unless it is explicitly part of the skill's stated purpose, which is not evident from this file alone.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd = f"uv run {script_path} {' '.join(all_codes)}"
    
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        # 解析输出 - 按顺序匹配
        lines = result.stdout.strip().split('\n')[2:]  # 跳过表头
        data = {}
Confidence
95% confidence
Finding
The code builds a shell command string and executes it with shell=True, which is dangerous because shell parsing introduces command-injection risk if any argument or path becomes attacker-controlled through configuration, environment, or future code changes. In a skill environment that chains other local skills, this also expands the trust boundary to external scripts and the shell interpreter, making unintended command execution more likely and more damaging.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The manifest describes capital market anomaly and delta reports focused on Chinese and global markets, with equity/media-source controls and web-search/scraper based reporting. This code adds a separate capability by shelling out to a different skill for cryptocurrency pricing, which is not mentioned in the manifest and is not necessary to implement the stated stock/news reporting purpose.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The function builds and runs another shell command to invoke a separate script for cryptocurrency pricing. Although the skill later prints a generic '正在获取数据...' message, it does not specifically disclose that an external subprocess will be executed, which is the kind of safety-relevant behavior this rule asks to warn about in code files.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd = f"uv run {script_path} {symbol}"
    
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
        # 解析: "Bitcoin (BTC): $67,947.09"
        line = result.stdout.strip()
        if "$" in line:
Confidence
94% confidence
Finding
This subprocess call has the same unsafe pattern: a shell command string is constructed and executed with shell=True. Although the current symbol is hardcoded to BTC, the function accepts a parameter and could become user-influenced later, so the pattern is a real injection and command-execution risk rather than a purely theoretical issue.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest claims enforced coverage of specific Chinese sources such as 华尔街见闻、东方财富 and global outlets including Reuters, but the code's report template instead lists 36氪、人民网 and omits several declared sources. This is a direct description-behavior mismatch because the implemented source set presented to the user differs from the manifest's promised media whitelist and coverage model.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The header comment and printed messaging state that the script gets recent 24-hour events and only focuses on news within the last 24 hours. However, although L12 computes a 24-hour cutoff timestamp, that value is never used; the script simply prints the first N items returned by each feed without comparing article times against the cutoff.

Static analysis

No suspicious patterns detected.