Back to skill

Security audit

场外基金查询

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent public fund lookup tool, but users should know it fetches financial data over unauthenticated HTTP.

Install only if you are comfortable with the skill contacting public fund-data APIs for the fund codes you ask about. Treat returned financial values as informational, because the current HTTP transport can be intercepted or modified on the network; do not rely on it alone for financial decisions.

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

Warning
Location
scripts/fund_query.py:65
Finding

Unauthenticated HTTP Transport Permits Financial Data Tampering

Content
View full analysis

Vulnerability Details

File Location: scripts/fund_query.py, lines 65, 99, and 135-141
Vulnerability Type: Plaintext HTTP transport for external financial-data APIs
Risk Level: Medium

Vulnerable Code

python
def get_estimate(fund_code: str) -> dict:
    """查询实时估值"""
    url = f"http://fundgz.1234567.com.cn/js/{fund_code}.js"
python
def get_info(fund_code: str) -> dict:
    """查询基金基本信息"""
    url = f"http://fund.eastmoney.com/pingzhongdata/{fund_code}.js"
python
def get_history(fund_code: str, page_size: int = 10) -> dict:
    """查询历史净值"""
    url = f"http://api.fund.eastmoney.com/f10/lsjz?fundCode={fund_code}&pageIndex=1&pageSize={page_size}"
    try:
        req = urllib.request.Request(url, headers={
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
            'Referer': 'http://fund.eastmoney.com/'
        })
        with urllib.request.urlopen(req, timeout=10) as resp:
            data = json.loads(resp.read().decode('utf-8'))

The shared request helper also sends a plaintext HTTP Referer:

python
req = urllib.request.Request(url, headers={
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
    'Referer': 'http://fund.eastmoney.com/'
})
with urllib.request.urlopen(req, timeout=10) as resp:
    return resp.read().decode('utf-8', errors='ignore')

Technical Analysis

Every external endpoint is addressed through unencrypted HTTP. HTTP provides neither confidentiality nor server authentication nor integrity protection. Consequently, an attacker with a suitable network position—such as a compromised gateway, hostile Wi-Fi access point, malicious proxy, or upstream network adversary—can observe requests and alter responses in transit.

The application trusts the returned JSON, JSONP, and JavaScript-derived fields and uses them to generate user-visible fund names, estimated values, percentages, dates, and historical NAV records ...[truncated 1720 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace every API URL with an HTTPS endpoint supported by the provider:
    • https://fundgz.1234567.com.cn/...
    • https://fund.eastmoney.com/...
    • https://api.fund.eastmoney.com/...
  2. Change the Referer to HTTPS where required by the service.
  3. Preserve Python's default TLS certificate and hostname verification; do not install an unverified SSL context.
  4. Prevent HTTPS-to-HTTP redirect downgrades by using a redirect handler that rejects any redirect whose destination scheme is not HTTPS.
  5. Fail closed when authenticated HTTPS transport is unavailable rather than retrying through HTTP.
  6. Validate response schemas and expected field types before formatting results.
  7. Constrain or escape remote textual fields before embedding them in Markdown output.
  8. Where the provider offers authenticity controls, verify signed responses or compare critical financial values against an independent trusted source.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documentation indicates execution of a Python script that queries a public fund API, which implies outbound network access, but the skill declares no explicit tool scope or permissions. That creates an unnecessary trust gap: a runtime or agent may allow broader network behavior than intended, and reviewers cannot easily verify that access is limited to the expected endpoint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring, usage instructions, and examples are presented entirely in Chinese, and the script's runtime messages also assume Chinese output. For a general-purpose fund query tool, this imposes a specific language/locale without opt-in or justification, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
99% confidence
Finding

The script sends requests to external fund APIs over plain HTTP rather than HTTPS, including at least the historical NAV endpoint and also other Eastmoney endpoints in the file. Plain HTTP allows man-in-the-middle tampering and response injection, so an attacker on the network path could alter fund data returned to the user, causing misinformation and undermining trust or downstream financial decisions.

Content

Scanner excerpt · scripts/fund_query.py (reported line 136)May include surrounding context.

python
def get_history(fund_code: str, page_size: int = 10) -> dict:
    """查询历史净值"""
    url = f"http://api.fund.eastmoney.com/f10/lsjz?fundCode={fund_code}&pageIndex=1&pageSize={page_size}"
    try:
        req = urllib.request.Request(url, headers={
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest says the skill is for querying real-time valuation, NAV, and basic information, but the code documentation and implementation explicitly add a history command for historical NAV data. Historical data access is a broader capability than the manifest description focused on current fund values and basic info.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.