Back to skill

Security audit

Claw Stock Watcher Pro

Security checks for vulnerabilities and agentic risk

Overview

The skill is a straightforward Chinese stock watchlist helper that stores a local watchlist and fetches stock-page data, with some usability and safety caveats but no hidden or malicious behavior found.

Install only if you are comfortable with a skill storing a local stock watchlist under ~/.clawdbot/stock_watcher and fetching stock pages from 10jqka.com.cn. Back up the watchlist before using clear or uninstall, and consider installing Python dependencies in a virtual environment with pinned versions.

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)

T08 · Insecure Dependencies

Warning
Location
scripts/install.sh:18
Finding
Unpinned Third-Party Dependencies Create Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install.sh:18-21`; `README.md:76-79` **Vulnerability Type**: Unpinned and unhashed third-party dependencies **Risk Level**: Medium ### Vulnerable Code `scripts/install.sh:18-21`: ```bash # Check if required Python packages are available if ! python3 -c "import requests, bs4" 2>/dev/null; then echo "Warning: Required Python packages (requests, beautifulsoup4) not found." echo "You may need to install them with: pip install requests beautifulsoup4" fi ``` `README.md:76-79`: ```bash Ensure you have Python 3 and required packages installed: ```bash pip3 install requests beautifulsoup4 ``` ``` ### Technical Analysis The project instructs users to install `requests` and `beautifulsoup4` without specifying reviewed versions, package hashes, a lockfile, a trusted package index, or an isolated environment. Consequently, the effective dependency code can change independently of the audited skill. The package names shown are established packages, and the project does not intentionally reference a known malicious package. The risk arises from mutable dependency resolution: a compromised upstream release, package-index compromise, or malicious dependency update could be selected when a user follows the documented command. The installation script only prints the command rather than executing it automatically. Exploitation therefore requires a user or automation system to follow the installation guidance. ### Attack Path 1. An attacker compromises a dependency release, its maintainer account, or the package-distribution channel. 2. A new malicious or compromised version becomes the version selected by an unconstrained `pip install`. 3. A user follows the command in `README.md` or the recommendation printed by `scripts/install.sh`. 4. Pip downloads and installs the mutable dependency version. 5. Malicious package installation behavior or subsequently imported package code executes under the inst ...[truncated 558 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a reviewed dependency manifest with exact versions, for example: ```text requests==<reviewed-version> \ --hash=sha256:<approved-wheel-hash> beautifulsoup4==<reviewed-version> \ --hash=sha256:<approved-wheel-hash> ``` 2. Install with hash verification: ```bash python3 -m pip install --require-hashes -r requirements.txt ``` 3. Generate and commit a lockfile using a dependency-locking tool, including pinned transitive dependencies. 4. Specify an approved HTTPS package index rather than relying on ambient pip configuration. 5. Recommend installation inside a dedicated virtual environment instead of the user's global Python environment. 6. Regularly review and update pinned versions after security testing rather than allowing automatic selection of new releases. 7. Update both `README.md` and `install.sh` so their dependency instructions remain consistent. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/add_stock.py:12
Finding
Missing Input Validation Allows Watchlist Record and Terminal-Output Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/add_stock.py:12-20`, `scripts/add_stock.py:34-72`, and `scripts/add_stock.py:77-84` **Vulnerability Type**: Improper input validation and unsafe plaintext record construction **Risk Level**: Low ### Vulnerable Code `scripts/add_stock.py:12-20`: ```python def get_stock_name_from_code(stock_code): """Get stock name from 10jqka.com.cn using stock code""" try: url = f"https://stockpage.10jqka.com.cn/{stock_code}/" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } response = requests.get(url, headers=headers, timeout=10) response.encoding = 'utf-8' ``` `scripts/add_stock.py:34-72`: ```python def add_stock(stock_code, stock_name=None): """Add stock to watchlist.txt in the correct location""" # Ensure the directory exists os.makedirs(os.path.dirname(WATCHLIST_FILE), exist_ok=True) # Get stock name if not provided if not stock_name: stock_name = get_stock_name_from_code(stock_code) if not stock_name: stock_name = stock_code # fallback to code if name cannot be fetched # Read existing watchlist existing_stocks = [] if os.path.exists(WATCHLIST_FILE): with open(WATCHLIST_FILE, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if line: existing_stocks.append(line) # Check if stock already exists stock_entry = f"{stock_code}|{stock_name}" stock_exists = False for existing in existing_stocks: if existing.startswith(f"{stock_code}|"): stock_exists = True break if stock_exists: print(f"Stock {stock_code} already in watchlist") return False # Add new stock existing_stocks.append(stock_entry) # Write back to file with proper newl ...[truncated 2612 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate the stock code before any network request or file operation: ```python import re if not re.fullmatch(r"[0-9]{6}", stock_code): raise ValueError("Stock code must contain exactly six digits") ``` 2. Reject structural and control characters in stock names: ```python if any(ch in stock_name for ch in ("|", "\r", "\n")): raise ValueError("Stock name contains prohibited characters") if any(ord(ch) < 32 or ord(ch) == 127 for ch in stock_name): raise ValueError("Stock name contains control characters") ``` 3. Apply a reasonable maximum name length to prevent oversized records and output abuse. 4. Validate remotely extracted stock names using the same rules before storing them. 5. Replace the custom pipe-delimited format with a structured serializer such as JSON, while still validating control characters before terminal display. 6. Escape or strip terminal control sequences before printing stored values. 7. Parse records using a strict schema and reject malformed entries rather than displaying them as raw text. 8. Add tests covering nonnumeric codes, newline injection, delimiter injection, terminal escape sequences, empty values, and excessively long input. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
There is a description/behavior mismatch because the declared purpose presents the skill as a full watchlist manager and monitor, but the provided code chunk is narrowly limited to summarizing performance for entries already present in a local watchlist file. The network access to 10jqka.com.cn is consistent with the description, and reading a local watchlist file is also aligned with monitoring a watchlist. However, core declared capabilities such as adding, removing, and listing stocks are absent from this code. Therefore, the code does not fully or accurately represent the broader declared functionality.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README documents a destructive 'clear watchlist' command with no warning, confirmation guidance, or note that it irreversibly deletes user-maintained data. In an agent or copy-paste workflow, this increases the chance of accidental data loss because users may run the command without understanding its effect.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The uninstallation section provides a command that removes both the skill and all watchlist data, but the warning appears only after the command rather than before it. This creates a realistic risk of accidental irreversible deletion, especially when users skim documentation or automated agents execute the first available uninstall instruction.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill describes file read/write and network-backed behavior but does not declare any explicit tool scope or permissions boundaries. In an agent environment, this can lead to overbroad capability exposure, making it harder to enforce least privilege and increasing the risk of unintended filesystem or network access.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill advertises a full watchlist clear operation without an explicit warning or confirmation step for irreversible data loss. In an agentic context, destructive operations can be triggered too easily, causing accidental deletion of user-maintained data.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The uninstall instructions state that all related files are completely removed, but do not clearly warn that stored watchlist data will also be deleted. Users may reasonably assume uninstalling removes only the skill and not their personal tracked data, leading to unintended data loss.

Session Persistence

Medium
Category
Rogue Agent
Content
echo "Installing stock-watcher skill dependencies..."

# Create the watchlist directory
mkdir -p ~/.clawdbot/stock_watcher

# Create empty watchlist file if it doesn't exist
Confidence
60% 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.

Natural-Language Policy Violations

Low
Confidence
79% confidence
Finding
Several core usage sections are written in Chinese while the surrounding document is in English, and the skill does not state that it is Chinese-only or offer an opt-in language choice. This can violate a language/locale policy when a specific language is effectively imposed without user selection.

Static analysis

No suspicious patterns detected.