Back to skill

Security audit

港股美股分析

Security checks for vulnerabilities and agentic risk

Overview

This stock-analysis skill needs review because it can give trading advice from simulated random indicators and includes an exposed API token, although I found no evidence of persistence or host compromise.

Review carefully before installing. Treat its analysis as informational only, not trading advice; rotate/remove the embedded Finnhub token, require user-provided credentials through a safe channel, disclose all network data sources, narrow triggers, and disable recommendations whenever real historical market data is unavailable.

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
analyze_stock.py:93
Finding
Hardcoded Finnhub API Credential Exposed in Source Code## Vulnerability Details **File Location**: `analyze_stock.py:93-101`; additional occurrences in `company_info.py:3-6`, `jd_logistics.py:4-7`, `report_v2.py:112-120`, `stock_analyst.py:39,103-110`, and `test_stock.py:5-9` **Vulnerability Type**: Hardcoded API credential and credential transmission in URL query parameters **Risk Level**: Medium ### Vulnerable Code ```python def get_us_stock(code): """获取美股行情""" FINNHUB_KEY = 'd6nucg1r01qse5qn5e90d6nucg1r01qse5qn5e9g' code = code.strip().upper() url = f'https://finnhub.io/api/v1/quote?symbol={code}&token={FINNHUB_KEY}' try: r = requests.get(url, timeout=10).json() ``` The primary implementation also retains the exposed credential as a fallback: ```python FINNHUB_KEY = os.environ.get( 'FINNHUB_API_KEY', 'd6nucg1r01qse5qn5e90d6nucg1r01qse5qn5e9g' ) ``` ### Technical Analysis A live-looking Finnhub API token is embedded directly in multiple version-controlled Python files. Anyone able to read the package or its repository history can recover and reuse it without running the Skill. Although `stock_analyst.py` supports the `FINNHUB_API_KEY` environment variable, its hardcoded fallback defeats secure secret injection. Other implementations always use the embedded value. The token is also appended to request URLs. Query-string credentials can be recorded by application logs, HTTP client diagnostics, proxies, monitoring systems, or error reports. HTTPS protects the request in transit but does not prevent exposure at endpoints or in logs. ### Attack Path 1. An attacker downloads the public project or obtains a distributed copy. 2. The attacker searches the source for `FINNHUB_KEY` or `token=`. 3. The attacker extracts the embedded Finnhub token. 4. The attacker sends independent requests to Finnhub using that token. 5. The attacker consumes the associated quota, triggers rate limits, or uses any other ...[truncated 708 chars]
Remediation
## Remediation Suggestions 1. Revoke and rotate the exposed Finnhub token immediately. 2. Remove the credential from every source and test file, including all hardcoded fallback values. 3. Purge the credential from repository history where operationally feasible. Rotation remains mandatory because history rewriting cannot invalidate existing copies. 4. Require `FINNHUB_API_KEY` to be supplied through a secret manager or environment variable and fail safely when it is absent: ```python FINNHUB_KEY = os.environ.get("FINNHUB_API_KEY") if not FINNHUB_KEY: raise RuntimeError("FINNHUB_API_KEY is required") ``` 5. Use Finnhub's recommended authorization mechanism. If query-parameter authentication is unavoidable, configure logging and monitoring systems to redact the `token` parameter. 6. Add automated secret scanning to pre-commit and CI workflows. 7. Apply a narrowly scoped API credential, quota alerts, rotation procedures, and usage monitoring.

other

Warning
Location
report_v2.py:138
Finding
Random Synthetic Price History Is Presented as Actionable Technical Analysis## Vulnerability Details **File Location**: `report_v2.py:138-145, 173-198, 229-275` **Vulnerability Type**: Fabricated and nondeterministic financial-analysis data **Risk Level**: Medium ### Vulnerable Code The historical-data function does not retrieve historical prices: ```python def get_historical_prices(code, days=30): """ 获取历史价格用于计算技术指标 由于API限制,这里用模拟数据 实际应该调用K线接口 """ # 尝试从腾讯获取最近几天的收盘价 # 这里返回模拟数据用于演示 return None ``` The report instead generates random prices and presents indicators calculated from them: ```python # 3. 技术指标 (模拟数据) print("\n2. 技术指标") # 生成模拟历史数据进行计算 # 实际应该调用K线API获取真实历史数据 base_price = data['current'] prices = [] for i in range(30, 0, -1): # 模拟一些波动 import random variation = random.uniform(-0.03, 0.03) prices.append(base_price * (1 + variation)) prices.append(base_price) indicators = calculate_indicators(prices) if indicators: print(f" RSI(14): {indicators.get('rsi', 'N/A')}") print(f" MA5: {indicators.get('ma5', 'N/A')}") print(f" MA10: {indicators.get('ma10', 'N/A')}") print(f" MA20: {indicators.get('ma20', 'N/A')}") ``` The synthetic RSI then changes the final score and recommendation: ```python # RSI评分 rsi = indicators.get('rsi', 50) if rsi: if rsi > 70: score -= 10 rsi_msg = "RSI超买,可能回调" elif rsi < 30: score += 10 rsi_msg = "RSI超卖,可能反弹" else: rsi_msg = "RSI处于中性区间" # 评分结论 if score >= 70: recommendation = "建议买入" recommendation_reason = "多方力量较强" elif score >= 50: recommendation = "可以持有" recommendation_reason = "走势平稳" elif score >= 30: recommendation = "建议观望" recommendation_reason = "方向不明" else: recommendation = "注意风险" recommendation_reason = "可能面临调整" ``` ### Technical Analysis `report_v2.py` does not obtain real ...[truncated 1876 chars]
Remediation
## Remediation Suggestions 1. Replace synthetic prices with validated historical OHLCV candles from an appropriate market-data provider. 2. Verify ticker identity, market, timestamps, chronological ordering, trading-day gaps, currency, and minimum sample count before calculating indicators. 3. If historical data is unavailable, display the indicators as unavailable and exclude them from the score and recommendation. 4. Never silently substitute random demonstration data in a production analysis path. 5. If simulation remains available for development, isolate it behind an explicit flag such as `--demo`, prominently label every resulting value as simulated, and prohibit trading recommendations in that mode. 6. Make report generation deterministic for identical market inputs and add tests using fixed historical fixtures. 7. Record data source and market timestamp in each report so users can verify provenance and freshness. 8. Add a clear financial-risk disclaimer and distinguish descriptive market data from recommendations.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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 (68)

Tainted flow: 'url' from os.environ.get (line 109, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
for hk_code in [f'hk{code}', f'hk0{code}', f'hk00{code}']:
        try:
            url = f'https://qt.gtimg.cn/q={hk_code}'
            r = requests.get(url, timeout=8)
            text = r.text.strip()
            
            if 'none_match' in text:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.environ.get (line 109, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
try:
        url = f'https://finnhub.io/api/v1/quote?symbol={code}&token={FINNHUB_KEY}'
        r = requests.get(url, timeout=10).json()
        
        if r.get('c'):  # current price
            return {
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.environ.get (line 109, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
"""获取财经新闻"""
    try:
        url = 'https://ai.6551.io/open/free_hot?category=macro'
        r = requests.get(url, timeout=15)
        data = r.json()
        
        if data.get('success'):
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 9, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
for sym in symbols:
    url = f'https://api.longbridgeapp.com/v1/quote/quotes?symbol={sym}'
    try:
        r = requests.get(url, headers=headers, timeout=10)
        print(f"=== {sym} ===")
        print(r.status_code)
        print(r.text[:500])
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
If the skill broadens into crypto/tech/macro hot-news sourcing through undeclared APIs, it exceeds the documented stock-analysis scope and introduces hidden network/data dependencies. In a financial setting, mixing unrelated news feeds with purported stock analysis can mislead users about provenance and relevance.

Vague Triggers

High
Confidence
95% confidence
Finding
The trigger list contains broad everyday terms such as report-like and market-related words that can match ordinary conversation. This can cause unintended invocation of a network-enabled financial skill, leading to unnecessary data access, confusing context hijacks, and outputs presented when the user did not intend to call this capability.

Lp3

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding
The skill declares executable/runtime requirements and browser/network-capable behavior but does not define any explicit tool scope such as allowed tools or permissions. In practice, this can let the agent invoke broader environment or network access than reviewers and users expect, increasing the blast radius if the skill is abused or behaves unexpectedly.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The skill metadata and invocation examples are primarily written in Chinese, and the trigger set is largely Chinese-language, which effectively constrains use to a specific language without stating that this is optional or user-selectable. The file does not document this as a justified region-specific restriction or offer an alternative language path.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill's docstrings, status messages, analysis labels, and recommendations are all fixed in Chinese, and the code does not provide any language selection or opt-in mechanism. This can violate language/locale policy when a skill forces a specific language without user choice or an explicitly justified regional constraint.

Static analysis

No suspicious patterns detected.