Back to skill

Security audit

加密货币与贵金属监控(国内源)

Security checks for vulnerabilities and agentic risk

Overview

This price monitor is not obviously malicious, but it should be reviewed because it uses tamperable market data and unsafe temporary files.

Install only if you are comfortable with a shell-based monitor contacting third-party price APIs and writing local cache/history files. Do not run it as root or from privileged automation, and treat the metals prices and change percentages as informational only because one feed uses HTTP and the local history can be tampered with.

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

Warning
Location
crypto-monitor.sh:16
Finding

Predictable Shared Temporary Files Permit Symlink-Based File Overwrite and Cache Tampering

Content
View full analysis
/dev/null || echo "0") if [ $((now - cache_time)) -lt 3600 ]; then cat "$cache_file" return fi 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 mkdir -p /tmp/crypto-monitor echo "{\"rate\":$rate,\"timestamp\":$now}" > "$cache_file" cat "$cache_file" } ``` The same insecure pattern is used for these predictable paths: ```bash local cache_file="/tmp/crypto-monitor/prices.json" local cache_file="/tmp/crypto-monitor/metals.json" local history_file="/tmp/crypto-monitor/metals_history.json" ``` The metals data is subsequently written through those paths: ```bash mkdir -p /tmp/crypto-monitor echo "{\"gold\":$gold,\"silver\":$silver,\"gold_usd\":$gold_usd,\"silver_usd\":$silver_usd,\"timestamp\":$now}" > "$history_file" cat > "$cache_file" << EOF {"gold":$gold,"gold_cny":$gold_cny,"gold_usd":$gold_usd,"gold_change":$gold_change,"silver":$silver,"silver_cny":$silver_cny,"silver_usd":$silver_usd,"silver_change":$silver_change} EOF ``` ### Technical Analysis The script stores mutable state under the fixed, system-wide path `/tmp/crypto-monitor`. It does not: - Create the directory with restrictive permissions. - Verify that the directory belongs to the current user. - Verify that cache files are regular files rather th ...[truncated 2758 chars]
Remediation
View remediation
&2 return 1 fi ``` 5. Write updates atomically using a temporary file created inside the trusted directory: ```bash tmp_file=$(mktemp "$cache_root/exchange.json.XXXXXX") || exit 1 printf '%s\n' "$json" > "$tmp_file" chmod 600 "$tmp_file" mv -f -- "$tmp_file" "$cache_file" ``` 6. Avoid running the price-monitoring script with elevated privileges. Document that it is intended to run as an ordinary user. 7. Validate the type, ownership, permissions, schema, and numeric ranges of existing cache content before trusting it. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
crypto-monitor.sh:93
Finding

Precious-Metals Prices Are Retrieved over Unauthenticated Plaintext HTTP

Content
View full analysis
/dev/null || echo "") ``` The response is trusted when it contains an expected status field and is then parsed into displayed and cached prices: ```bash if [ -n "$resp" ] && echo "$resp" | grep -q '"code":200'; then gold_cny=$(echo "$resp" | python3 -c "import sys,json; d=json.load(sys.stdin); items=[i for i in d['data']['list'] if i.get('title')=='黄金']; print(items[0]['num3'] if items else 0)" 2>/dev/null || echo "0") silver_cny=$(echo "$resp" | python3 -c "import sys,json; d=json.load(sys.stdin); items=[i for i in d['data']['list'] if i.get('title')=='白银']; print(items[0]['num3'] if items else 0)" 2>/dev/null || echo "0") gold_usd=$(echo "$resp" | python3 -c "import sys,json; d=json.load(sys.stdin); items=[i for i in d['data']['list'] if i.get('title')=='伦敦金']; print(items[0]['num3'] if items else 2650)" 2>/dev/null || echo "2650") silver_usd=$(echo "$resp" | python3 -c "import sys,json; d=json.load(sys.stdin); items=[i for i in d['data']['list'] if i.get('title')=='伦敦银']; print(items[0]['num3'] if items else 31.20)" 2>/dev/null || echo "31.20") fi ``` ### Technical Analysis The primary precious-metals endpoint uses HTTP rather than HTTPS. HTTP provides neither server authentication nor transport integrity. Any party able to intercept or influence the network connection can read, replace, or modify the API response. Checking for the string `"code":200` is not an authenticity check. An attacker can return syntactically valid JSON containing that field and arbitrary values in the expected `data.list` entries. The script then writes those values to its cache and history files and presents them as current market prices. ...[truncated 1483 chars]
Remediation
View remediation
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 (10)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The deletion target is a fixed wildcard under /tmp, which is a shared, attacker-influencable filesystem location. While the command is not parameter-injected, unsafe use of predictable files in /tmp means a local attacker may be able to manipulate files or symlinks in that directory so refresh removes or interacts with unintended targets, especially if the script is run by another user or with elevated privileges.

Content

Scanner excerpt · crypto-monitor.sh (reported line 274)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
85% confidence
Finding

The skill documentation exposes shell-invocable commands (crypto-monitor all, refresh, help) but does not declare any permissions or allowed-tools scope. This creates an authorization gap: an agent or reviewer cannot tell what execution capabilities are intended, making unintended shell access or over-broad execution more likely if the implementation is installed alongside this metadata.

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")

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The comment Calculate change and later output labels present the metals delta as 24h, but the implementation reads whatever previous value is in /tmp/crypto-monitor/metals_history.json and computes a percentage from that sample. Because the prior sample could be minutes ago, hours ago, or manually injected via update, the code does not actually compute a 24-hour change.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest describes a monitoring skill for crypto and precious-metals prices, which implies fetching and displaying market data. The update command instead lets a user inject arbitrary gold and silver values into the local history file, affecting subsequent change calculations rather than just monitoring external prices.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The refresh branch runs rm -f /tmp/crypto-monitor/*.json, which removes local cache/history files, but there is no user confirmation, warning, or help text disclosure describing this deletion behavior. Even though the files are temporary, this is a destructive file operation that should be communicated to the user.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

Natural-language output, comments, and help content prominently assume Chinese alongside English, and the script provides no mechanism to select or opt into a preferred locale. Under the policy, forcing a specific language or locale without user choice can be a natural-language policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This shell script makes outbound HTTP requests to third-party services to fetch exchange and asset prices, but there is no explicit warning in the code's help output or around execution that user/system network access will occur. For a code file, external network calls should have some visible disclosure unless clearly communicated to the user.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script writes predictable cache and history files under /tmp, a world-writable location shared across users on many systems. This can enable local tampering, symlink attacks, or data spoofing that affects the script's output and file writes, especially if run in a more privileged context.

Content

No source excerpt is available for this finding.