Back to skill

Security audit

彩票查询 - 即刻数据

Security checks for vulnerabilities and agentic risk

Overview

The skill is a lottery lookup tool, but it needs review because an undocumented endpoint override can send the user's Jike API key to a non-Jike host.

Install only if you are comfortable providing a Jike API AppKey. Prefer a host-managed environment variable over scripts/.env, do not set JIKE_API_BASE_URL unless you fully trust the destination, and treat the AppKey as sensitive because the script sends it in request URLs.

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/caipiao_lottery_query.py:168
Finding

Unvalidated API Endpoint Override Can Disclose the AppKey

Content
View full analysis

Vulnerability Details

File Location: scripts/caipiao_lottery_query.py:25 and scripts/caipiao_lottery_query.py:168-170
Vulnerability Type: Arbitrary API endpoint override and credential disclosure
Risk Level: Medium

Vulnerable Code

python
API_BASE_URL = os.environ.get("JIKE_API_BASE_URL", "https://api.jikeapi.cn").rstrip("/")
python
url = f"{API_BASE_URL}{API_PATH_MAP[command]}?{urllib.parse.urlencode({**params, 'appkey': appkey})}"
try:
    with urllib.request.urlopen(url, timeout=15) as response:

Technical Analysis

The undocumented JIKE_API_BASE_URL environment variable can replace the trusted API origin with an arbitrary URL. The application does not validate the URL scheme, hostname, port, or destination before appending the user's AppKey and issuing the request.

Because the AppKey is included in the URL query string, a process launcher, wrapper, compromised execution environment, or other actor capable of controlling environment variables can redirect the request to an attacker-controlled server. The resulting request transmits the legitimate credential outside the intended api.jikeapi.cn trust boundary.

This behavior exceeds the documented purpose of communicating with the Jike API and creates a credential-exfiltration path. Placing the credential in the query string also increases its potential exposure through server access logs, proxy logs, and diagnostic tooling.

Attack Path

  1. The victim configures a valid AppKey through JIKE_CAIPIAO_LOTTERY_QUERY_KEY, JIKE_APPKEY, the command line, or scripts/.env.
  2. An attacker or compromised launcher sets JIKE_API_BASE_URL to an attacker-controlled endpoint, such as https://attacker.example.
  3. The victim invokes any documented command, such as latest or detail.
  4. load_appkey() retrieves the victim's legitimate AppKey.
  5. request_api() constructs a URL under the attacker-controlled origin and ad ...[truncated 736 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the JIKE_API_BASE_URL override from production code and use a fixed trusted endpoint:

    python
    API_BASE_URL = "https://api.jikeapi.cn"
    
  2. If endpoint substitution is required for development or testing, make it an explicit development-only feature and enforce:

    • An exact allowlist of approved hostnames.
    • HTTPS as the only permitted scheme.
    • Rejection of embedded credentials, fragments, unexpected ports, and non-public or local destinations.
    • A separate test credential that cannot access production resources.
  3. Validate the parsed endpoint before every request. Do not rely on string-prefix checks; use urllib.parse.urlparse() and compare the normalized scheme and hostname against an allowlist.

  4. Prefer sending the credential in an authorization header if supported by the service rather than in the query string. This reduces exposure through URL logs and diagnostic output.

  5. Ensure redirects cannot forward credentials to an untrusted origin. Disable redirects or verify the destination origin before following them when sensitive credentials are attached.

  6. Add automated tests confirming that HTTP URLs, unapproved domains, loopback addresses, private-network destinations, and malformed endpoints are rejected before any credential-bearing request is sent.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Tainted flow: 'url' from os.environ.get (line 177, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
93% confidence
Finding

The request URL is built from API_BASE_URL, which is sourced from the JIKE_API_BASE_URL environment variable without validation. If an attacker can influence the runtime environment, they can redirect requests containing the AppKey to an arbitrary host, causing secret exfiltration and potentially turning the script into an SSRF primitive. The skill context makes this more serious because the same request also includes sensitive credential material in the query string.

Content

Scanner excerpt · scripts/caipiao_lottery_query.py (reported line 179)May include surrounding context.

python
"""
    url = f"{API_BASE_URL}{API_PATH_MAP[command]}?{urllib.parse.urlencode({**params, 'appkey': appkey})}"
    try:
        with urllib.request.urlopen(url, timeout=15) as response:
            return json.loads(response.read().decode("utf-8"))
    except urllib.error.HTTPError as exc:
        return {"code": exc.code, "message": f"接口请求失败: HTTP {exc.code}", "data": ""}

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The skill instructs users to write the API key into scripts/.env, a file under the project directory. Storing credentials in a workspace-local file increases the chance of accidental inclusion in archives, commits, logs, or broader file reads by other tools running in the same environment.

Content

Scanner excerpt · SKILL.md (reported line 30)May include surrounding context.

方式二:通用环境变量

export JIKE_APPKEY=你的AppKey

方式三:脚本目录 .env 文件(本地测试使用)

echo "JIKE_CAIPIAO_LOTTERY_QUERY_KEY=你的AppKey" > scripts/.env

text

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

This line continues the recommendation to store the AppKey in scripts/.env, creating a credential-at-rest risk within the skill directory. In a skill ecosystem where files may be packaged, inspected, or broadly readable by automation, local secret files materially raise exposure risk.

Content

Scanner excerpt · SKILL.md (reported line 31)May include surrounding context.

export JIKE_APPKEY=你的AppKey

方式三:脚本目录 .env 文件(本地测试使用)

echo "JIKE_CAIPIAO_LOTTERY_QUERY_KEY=你的AppKey" > scripts/.env

text

Windows 用户可在系统环境变量中新增:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/caipiao_lottery_query.py (reported line 65)May include surrounding context.

python
env_value = os.environ.get(env_name, "").strip()
        if env_value:
            return env_value
    env_file = Path(__file__).parent / ".env"
    if not env_file.exists():
        return ""
    for line in env_file.read_text(encoding="utf-8").splitlines():

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill declares executable behavior that uses environment variables, local files, and outbound network access, but it does not define an explicit tool scope such as permissions or allowed-tools. This creates an unnecessary trust gap: a host agent may grant broader capabilities than needed, increasing the blast radius if the script is modified, abused, or invoked in an unexpected environment.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 100)May include surrounding context.

md
"title": "彩票查询 - 即刻数据",
  "description": "查询彩票最新开奖、指定彩种期开奖详情、福彩3D/排列3历史号码和冷热号统计。",
  "env": "JIKE_CAIPIAO_LOTTERY_QUERY_KEY",
  "api_url": "https://api.jikeapi.cn/v1/caipiao/lottery/latest",
  "homepage": "https://www.jikeapi.cn/"
}

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 101)May include surrounding context.

md
"title": "彩票查询 - 即刻数据",
  "description": "查询彩票最新开奖、指定彩种期开奖详情、福彩3D/排列3历史号码和冷热号统计。",
  "env": "JIKE_CAIPIAO_LOTTERY_QUERY_KEY",
  "api_url": "https://api.jikeapi.cn/v1/caipiao/lottery/latest",
  "homepage": "https://www.jikeapi.cn/"
}

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 102)May include surrounding context.

md
"title": "彩票查询 - 即刻数据",
  "description": "查询彩票最新开奖、指定彩种期开奖详情、福彩3D/排列3历史号码和冷热号统计。",
  "env": "JIKE_CAIPIAO_LOTTERY_QUERY_KEY",
  "api_url": "https://api.jikeapi.cn/v1/caipiao/lottery/latest",
  "homepage": "https://www.jikeapi.cn/"
}

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 103)May include surrounding context.

md
"title": "彩票查询 - 即刻数据",
  "description": "查询彩票最新开奖、指定彩种期开奖详情、福彩3D/排列3历史号码和冷热号统计。",
  "env": "JIKE_CAIPIAO_LOTTERY_QUERY_KEY",
  "api_url": "https://api.jikeapi.cn/v1/caipiao/lottery/latest",
  "homepage": "https://www.jikeapi.cn/"
}

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · _meta.json (reported line 8)May include surrounding context.

json
"title": "彩票查询 - 即刻数据",
  "description": "查询彩票最新开奖、指定彩种期开奖详情、福彩3D/排列3历史号码和冷热号统计。",
  "env": "JIKE_CAIPIAO_LOTTERY_QUERY_KEY",
  "api_url": "https://api.jikeapi.cn/v1/caipiao/lottery/latest",
  "homepage": "https://www.jikeapi.cn/"
}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The AppKey is appended to the URL query string, which can be exposed through logs, proxies, browser/history equivalents, monitoring systems, and upstream servers. Even over HTTPS, query parameters are commonly recorded in application and infrastructure logs, increasing the chance of credential leakage.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Natural-language strings throughout the script, including help text, errors, and output, are fixed to Chinese. This can violate a language/locale policy when a skill forces a specific language without offering the user a choice or clearly documenting a justified locale restriction.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.