Back to skill

Security audit

加密货币与贵金属监控

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a market-price monitoring skill, but its shipped shell script has unsafe handling of external API data and shared temporary files that users should review before installing.

Install only if you are comfortable running a shell script that contacts third-party market APIs and writes cache/history files locally. Before regular use, the script should be hardened to validate all API and cache values as numbers, move storage to a private per-user cache directory, avoid following symlinks, and correct the advertised silver and 24h-change behavior.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
crypto-monitor.sh:125
Finding

API-Controlled Python Code Injection

Content
View full analysis
/dev/null || echo "$gold") local prev_silver=$(echo "$prev" | python3 -c "import sys,json; print(json.load(sys.stdin).get('silver', $silver))" 2>/dev/null || echo "$silver") ``` The interpolated values originate from external API responses: ```bash gold=$(echo "$gold_resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('price', 2650))" 2>/dev/null || echo "2650") ``` ### Technical Analysis The `$gold` and `$silver` shell variables are inserted directly into the source code passed to `python3 -c`. The values are not validated as finite numeric values before interpolation. In particular, `$gold` can originate from the GoldAPI.io or Yahoo Finance response. JSON parsing alone does not enforce a numeric type: if an API returns a JSON string, Python's `print()` emits that string, after which the shell inserts it into a subsequent Python program. The default argument supplied to `dict.get()` is evaluated before the method is called, even when the requested key already exists. Consequently, an injected Python expression in `$gold` or `$silver` is evaluated whenever these lines execute. ### Attack Path 1. An attacker compromises, controls, or successfully spoofs one of the external market-data responses. 2. The response contains a syntactically valid JSON value whose `price` field is a string containing a Python expression, such as an expression invoking `os.system()`. 3. The script parses and assigns that string to `$gold`. 4. A pre-existing `/tmp/crypto-monitor/metals_history.json` file causes the history-processing branch to execute. 5. The string is interpolated into the `python3 -c` program at line 125. 6. Pyth ...[truncated 747 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
crypto-monitor.sh:17
Finding

Symlink-Unsafe Predictable Files in a Shared Temporary Directory

Content
View full analysis
"$cache_file" cat "$cache_file" ``` ```bash mkdir -p /tmp/crypto-monitor cat > "$cache_file" << EOF {"btc_usd":$btc_usd,"btc_change":$btc_change,"eth_usd":$eth_usd,"eth_change":$eth_change} EOF cat "$cache_file" ``` ```bash mkdir -p /tmp/crypto-monitor echo "{\"gold\":$gold,\"silver\":$silver,\"timestamp\":$now}" > "$history_file" cat > "$cache_file" << EOF {"gold":$gold,"gold_change":$gold_change,"silver":$silver,"silver_change":$silver_change} EOF cat "$cache_file" ``` The manual update command has the same issue: ```bash mkdir -p /tmp/crypto-monitor echo "{\"gold\":$gold,\"silver\":$silver,\"timestamp\":$(date +%s)}" > "/tmp/crypto-monitor/metals_history.json" ``` ### Technical Analysis `/tmp` is a shared namespace. The script neither creates a unique private directory nor verifies that `/tmp/crypto-monitor` is owned by the current user and inaccessible to other users. Shell output redirection follows symbolic links. Therefore, if an attacker pre-creates the directory with permissive access and places a symbolic link at one of the expected JSON paths, the script writes to the symlink target. No regular-file check, `O_NOFOLLOW` equivalent, atomic tempo ...[truncated 1844 chars]
Remediation
View remediation
"$tmp_file" chmod 600 -- "$tmp_file" mv -f -- "$tmp_file" "$cache_dir/exchange.json" ``` Equivalent protection should be applied consistently to all exchange-rate, price, metal, and history files. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% 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).

Content

Scanner excerpt · crypto-monitor.sh (reported line 258)May include surrounding context.

sh
case "$cmd" in
        all|a) cmd_all ;;
        update|up) cmd_update "$@" ;;
        refresh|r) rm -f /tmp/crypto-monitor/*.json && cmd_all ;;
        help|--help|-h|"") cmd_help ;;
        *) echo -e "${RED}未知命令: $cmd${NC}"; cmd_help; exit 1 ;;
    esac

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises shell-style commands and operational behavior but does not declare any explicit tool scope or permissions. This creates an authorization ambiguity where an agent or reviewer cannot clearly constrain execution, increasing the risk of unintended shell access or command execution beyond the skill's documented purpose.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · crypto-monitor.sh (reported line 31)May include surrounding context.

sh
fi
    
    local rate=7.25
    local resp=$(curl -s --connect-timeout 3 "https://api.exchangerate-api.com/v4/latest/USD" 2>/dev/null || echo "")
    if [ -n "$resp" ]; then
        rate=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin)['rates'].get('CNY', 7.25))" 2>/dev/null || echo "7.25")
    fi

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · crypto-monitor.sh (reported line 56)May include surrounding context.

sh
local btc_usd=97500 btc_change=2.5 eth_usd=3450 eth_change=1.8
    
    local resp=$(curl -s --connect-timeout 3 "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum&vs_currencies=usd&include_24h_change=true" 2>/dev/null || echo "")
    
    if [ -n "$resp" ] && echo "$resp" | grep -q "bitcoin"; then
        btc_usd=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin)['bitcoin']['usd'])" 2>/dev/null || echo "97500")

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest says the skill monitors both gold (XAU) and silver (XAG) price movements. However, the implementation explicitly comments that silver is estimated as gold divided by 85 and does not query any silver market data source, so the reported XAG value is not an actual monitored price.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The displayed output labels metals movement as '24h涨跌 / 24h', and the nearby comment says 'Calculate change'. In reality, the code reads the previous local history file and computes percentage change from that single stored snapshot, which could be minutes or days old depending on prior runs, so it contradicts the implied 24-hour semantics.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

Although the script is bilingual in places, its primary headings, labels, and help output prominently include Chinese text by default, with no option to select a preferred language or locale. The stated policy flags language or locale constraints when a skill imposes them without user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest description and main heading present the skill content bilingually with Chinese-first wording, but there is no statement that the user can choose their preferred language or that the skill is intended for a specific locale. Under the policy, fixed language behavior without user opt-in can be a natural-language locale violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This shell script makes outbound HTTP requests to a third-party exchange-rate API, which necessarily exposes system metadata such as IP address and request timing. While the code purpose explains price retrieval, there is no visible user warning in comments, help text, or runtime output that external network access occurs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script queries CoinGecko, GoldAPI, and Yahoo Finance to fetch cryptocurrency and metals prices, but the user-facing help only mentions possible API rate limiting and does not clearly warn that external services are contacted. For a code file, outbound network operations should have at least some visible disclosure through comments, help text, or runtime messaging.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

A monitoring skill would be expected to report externally sourced market data. The update command instead writes user-supplied gold and silver values into the history file, affecting later displayed change calculations and introducing behavior beyond passive monitoring.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.