Back to skill

Security audit

Etf Assistant 1.0.1

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches an ETF quote assistant, but its calculator accepts unvalidated inputs that can execute shell commands locally.

Review before installing. Do not run the calc command with untrusted or agent-generated amount/year values until strict numeric validation is added. If installed anyway, use it only in a sandbox or with trusted numeric inputs, and expect price/compare to send ETF codes to Yahoo Finance.

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 (1)

T09 · Insecure Skill Coding Practices

Error
Location
etf-assistant.sh:232
Finding
Arbitrary Command Execution Through Bash Arithmetic Injection<![CDATA[ ## Vulnerability Details **File Location**: `etf-assistant.sh`, lines 232–250 **Vulnerability Type**: Bash arithmetic-expression injection **Risk Level**: High ### Vulnerable Code ```bash cmd_calc() { local code=$1 local amount=$2 local years=$3 if [ -z "$code" ] || [ -z "$amount" ] || [ -z "$years" ]; then echo -e "${RED}❌ 参数不全${NC}" echo "示例: $0 calc 510300 1000 10" echo "含义: 每月定投1000元,定投10年" return 1 fi local name=$(get_etf_name "$code") echo -e "${GREEN}📈 定投计算器${NC}" echo "━━━━━━━━━━━━━━━━━━━━" echo "ETF: $name ($code)" echo "月定投: ¥$amount" echo "定投年限: $years 年" echo "━━━━━━━━━━━━━━━━━━━━" echo "" # 简化计算 (假设年化收益率8%) local months=$((years * 12)) local annual_return=0.08 local monthly_return=$(echo "scale=6; $annual_return / 12" | bc) # 使用复利公式计算 local future_value=$(echo "scale=2; $amount * ((1 + $monthly_return)^$months - 1) / $monthly_return" | bc) local total_invest=$((amount * months)) ``` ### Technical Analysis The `amount` and `years` values come directly from command-line arguments and are checked only for emptiness. They are not validated as decimal integers before being evaluated by Bash arithmetic expansion. Bash arithmetic contexts do more than convert strings to numbers. Their operands are parsed as arithmetic expressions, and variable references can be recursively evaluated. Constructs such as array subscripts may trigger expansions, including command substitution, during arithmetic evaluation. The following statements are therefore dangerous sinks: ```bash local months=$((years * 12)) local total_invest=$((amount * months)) ``` An attacker-controlled arithmetic expression placed in `years` can be evaluated when `months` is assigned. A malicious expression in `amount` can similarly be evaluated when `total_invest` is assigned. The intermediate use of `amount` in the command sent to `bc` also al ...[truncated 1748 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Validate all calculator operands before they enter Bash arithmetic expansion or `bc`. Accept only a narrowly defined decimal representation and impose reasonable bounds: ```bash if ! [[ "$amount" =~ ^[1-9][0-9]*$ ]]; then echo "Amount must be a positive integer." >&2 return 1 fi if ! [[ "$years" =~ ^[1-9][0-9]*$ ]]; then echo "Years must be a positive integer." >&2 return 1 fi if (( amount > 100000000 || years > 100 )); then echo "Amount or duration exceeds the supported range." >&2 return 1 fi ``` After validation, force base-10 interpretation to prevent leading-zero values from being treated as octal: ```bash local amount_num=$((10#$amount)) local years_num=$((10#$years)) local months=$((years_num * 12)) local total_invest=$((amount_num * months)) ``` Construct the `bc` input exclusively from these validated numeric variables: ```bash local future_value future_value=$(printf '%s\n' \ "scale=2; $amount_num * ((1 + $monthly_return)^$months - 1) / $monthly_return" | bc) ``` Additional hardening should include: - Reject signs, whitespace, decimal points, variable names, brackets, parentheses, and shell metacharacters unless explicitly required. - Check for integer overflow before multiplication. - Use `local variable; variable=$(...)` rather than combining declaration and command substitution, so command failures are not masked by `local`. - Handle `bc` failures explicitly and return a nonzero status. - Run the Skill with a restricted account and minimal filesystem, environment, and network access. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

External Script Fetching

High
Category
Supply Chain
Content
echo ""
    
    # 获取两只ETF的行情
    local price1=$(curl -s "https://query1.finance.yahoo.com/v8/finance/chart/${code1}.SS" 2>/dev/null | python3 -c "
import json, sys
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
except: print('N/A')
" 2>/dev/null)
    
    local price2=$(curl -s "https://query1.finance.yahoo.com/v8/finance/chart/${code2}.SS" 2>/dev/null | python3 -c "
import json, sys
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
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
All user-facing strings, usage text, and command descriptions are presented only in Chinese, with no indication that the skill is region-specific or that users can opt into another language. This creates a language/locale policy issue because the skill implicitly enforces a single language without user choice.

Missing User Warnings

Low
Confidence
92% confidence
Finding
This shell script sends the user-provided ETF code to an external Yahoo Finance endpoint via curl, but there is no explicit warning, confirmation, or disclosure that the query will contact a third-party service. Although the code comment mentions Yahoo Finance, that is not user-facing and the help output does not inform users that their requests rely on a remote API.

Missing User Warnings

Low
Confidence
90% confidence
Finding
The compare command issues two curl requests to Yahoo Finance for the supplied ETF codes, but users are not informed in the CLI help or command output that external API calls will occur. This is a missing disclosure for a network operation that transmits user input to a third party.

Static analysis

No suspicious patterns detected.