CAUTION version 1.0.0 · audited 2026-09-09
Stock Watcher keeps a simple text list of Chinese A-share stock codes in a file under your home directory (~/.clawdbot/stock_watcher/watchlist.txt) and can add, remove, list, or clear entries. To look up a stock's name and recent percentage changes it fetches the public page for that code from stockpage.10jqka.com.cn and scrapes the HTML. The only network destination is that one public site, and the only data sent is the stock code in the URL. There are no credentials, payments, obfuscated code, downloads-and-execute, or persistence mechanisms. The uninstall script does an 'rm -rf' but only on the skill's own watchlist directory. Minor caveats: parsing is crude (it grabs the first three percentage strings on the page, which may be inaccurate), and clear/uninstall delete data with no confirmation or backup.
Instructions try to steer the agent beyond the declared purpose. summarize_performance.py fetches remote HTML from 10jqka.com.cn and extracts arbitrary text/percentages (line 45 'text_content = soup.get_text()', line 51 regex over the page) which is printed to stdout and then read by the agent. Remote page content is not sanitized, so text on the third-party page could reach the agent's context. No code executes the fetched content, so the risk is limited to prompt-injection through displayed text.
| Declared purpose | Manage a personal stock watchlist (add/remove/list/clear) and summarize recent performance of the watched Chinese A-share stocks using data from 10jqka.com.cn. |
| Observed behavior | Reads and writes a plain-text watchlist file in the user's home directory, makes outbound HTTPS GET requests to https://stockpage.10jqka.com.cn/{code}/ with a browser User-Agent, parses the returned HTML with BeautifulSoup, prints results to stdout, and provides shell scripts that create or delete the watchlist directory. No other network, credential, or system access. |
| Verdict, rules only | CAUTION · uses sudo, rm -rf or dd |
| Verdict, AI | SAFE |
| Final verdict | CAUTION (never better than either pass) |
| capability | vs purpose | detail |
|---|---|---|
| network | needed | HTTP GET to https://stockpage.10jqka.com.cn/{stock_code}/ in scripts/add_stock.py line 15 and scripts/summarize_performance.py line 18; only the stock code is transmitted. |
| filesystem_read | needed | Reads only ~/.clawdbot/stock_watcher/watchlist.txt (list_stocks.py line 18, remove_stock.py line 21, summarize_performance.py line 71). |
| filesystem_write | needed | Creates the watchlist directory and writes/truncates watchlist.txt (add_stock.py line 70, remove_stock.py line 41, clear_watchlist.py line 18, install.sh line 14). |
| shell | needed | install.sh creates the directory; uninstall.sh runs 'rm -rf' scoped to $HOME/.clawdbot/stock_watcher. |
| install_packages | needed | install.sh only checks for requests/bs4 and prints a suggested pip command; it does not install anything automatically (scripts/install.sh lines 19-21). |
| severity | finding |
|---|---|
| low | Unsanitized remote page text is scraped and surfaced to the agent All visible text of the third-party stock page is extracted and percentage strings from it are printed. Content controlled by the remote site (or an attacker able to influence it) ends up in the agent's output stream unfiltered. No execution occurs, so impact is limited to possible prompt injection or misleading numbers. scripts/summarize_performance.py:45 text_content = soup.get_text() |
| low | Crude scraping may report inaccurate figures The script simply takes the first three percentage-looking strings anywhere on the page and labels them 指标1/2/3. These may not be the stock's actual price change, so the summary should not be relied on for financial decisions. scripts/summarize_performance.py:51 percentages = re.findall(r'[-+]?\d+\.?\d*%', text_content) |
| low | Recursive delete during uninstall The uninstall script recursively deletes ~/.clawdbot/stock_watcher. The path is fixed and scoped to the skill's own data directory (guarded by an existence check on line 8), but the deletion is irreversible and there is no confirmation prompt. scripts/uninstall.sh:9 rm -rf "$WATCHLIST_DIR" |
| info | Watchlist is truncated without confirmation Opening the file in write mode erases all saved entries immediately with no backup or undo. Scoped to the skill's own file. scripts/clear_watchlist.py:18 with open(WATCHLIST_FILE, 'w', encoding='utf-8') as f: |
| info | Requests disguise themselves as a desktop browser A spoofed browser User-Agent is sent to 10jqka.com.cn. Common practice for scraping, but it means traffic is not identified as automated and may violate the site's terms of service. scripts/add_stock.py:17 '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' |
| info | Errors silently swallowed during name lookup Network or parsing failures are ignored (line 31 'pass') and the stock code is used as the name instead, so the user is not told the lookup failed. scripts/add_stock.py:30 except Exception as e: |
| info | Dependency install is advisory only The installer checks for the requests and beautifulsoup4 packages and only prints a suggestion; it does not silently install or upgrade anything. scripts/install.sh:21 echo "You may need to install them with: pip install requests beautifulsoup4" |
0 AI finding(s) were dropped because their file, line or quote did not match the package.
| domain | service rating | where |
|---|---|---|
| clawhub.ai | not in the service index | skill-card.md:7 |
| stockpage.10jqka.com.cn | not in the service index | README.md:53 |
| Binaries invoked | bash, pip, pip3, python3, rm -rf |
| Environment variables read | HOME, WATCHLIST_DIR, WATCHLIST_FILE |
| Hard-coded wallets | none |
| Pipes a download to a shell | 0 |
| eval / exec / subprocess | 0 |
| base64 blobs | 0 |
| File writes | 5 |
| Persistence | 0 |
| file | lines | sha256 |
|---|---|---|
README.md | 102 | 64ffed610197e88f… |
SKILL.md | 88 | 4d7b3616d674e7f1… |
_meta.json | 6 | 012f2f5d1eaeac57… |
scripts/add_stock.py | 84 | bca743d747731e33… |
scripts/clear_watchlist.py | 24 | 27aecee130f51eef… |
scripts/config.py | 13 | e36d2be7cb0f5df8… |
scripts/install.sh | 26 | 03bb45d2c74cbef0… |
scripts/list_stocks.py | 36 | 662e3bb19198d30a… |
scripts/remove_stock.py | 54 | 236ce33527f7a2af… |
scripts/summarize_performance.py | 100 | 7e8c67dae066e923… |
scripts/uninstall.sh | 13 | c943b43a17c1212a… |
skill-card.md | 40 | 23adb856533e9f30… |
For agents
JSON: https://agenteconomy.report/k/stock-watcher.audit.json · badge: https://agenteconomy.report/k/stock-watcher.audited.svg ·
skill rating: /k/stock-watcher · commission an audit of any skill: US$ 29 per version.
The complete published package of this exact version was downloaded from the registry and read statically; nothing was executed. A deterministic pass extracts network destinations, binaries, environment variables, writes, install commands, obfuscation markers, subprocesses and wallets, each with file and line. An AI then reads the whole package with those facts and writes the summary, the capabilities and the findings under a strict schema; every finding it produces must cite a file, a line and the exact text, or it is dropped. The final verdict is the worst of the two passes. The audit does not change the skill's trust tier (policy); the author may respond through the dispute channel and the response is published here. Commissioned by: the Agent Economy Report (free program: the 150 most downloaded skills, September 2026).