Back to skill

Security audit

节假日查询 - 即刻数据

Security checks for vulnerabilities and agentic risk

Overview

The skill performs the advertised holiday lookup, but its API key can be sent through an under-disclosed, environment-controlled endpoint, so it needs review before use.

Install only if you are comfortable sending holiday/date query data and your Jike AppKey to the provider. Before use, make sure JIKE_API_BASE_URL is unset or locked to the intended HTTPS Jike host, avoid passing the key with --key, and treat any shell history or logs containing the AppKey as sensitive.

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/calendar_holiday_query.py:26
Finding

API Credential Exposure Through Query Strings and an Unrestricted Configurable Endpoint

Content
View full analysis

Vulnerability Details

File Location: scripts/calendar_holiday_query.py, lines 26, 81, and 136-138
Vulnerability Type: API credential exposure and unrestricted credential destination
Risk Level: Medium

Vulnerable Code

python
API_BASE_URL = os.environ.get("JIKE_API_BASE_URL", "https://api.jikeapi.cn").rstrip("/")
python
parser.add_argument("--key", dest="cli_key", help="Temporarily provide the Jike Data AppKey")
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"))

Technical Analysis

The application inserts the AppKey directly into the URL query string. Query-string credentials can be recorded in web server logs, reverse-proxy logs, network diagnostics, monitoring systems, and URL telemetry. Supplying the key with --key can additionally expose it through shell history and local process listings.

The API destination is controlled by the undocumented JIKE_API_BASE_URL environment variable without scheme or hostname validation. Consequently, any party capable of influencing the process environment can direct an otherwise legitimate holiday query to an arbitrary endpoint. Because the AppKey is appended before urlopen() sends the request, that endpoint receives the credential. A value using plain HTTP could also transmit the key without transport encryption.

This does not independently let a remote attacker modify the environment. Exploitation requires influence over the execution environment, service configuration, wrapper script, CI job, container configuration, or command invocation.

Attack Path

  1. The attacker gains the ability to set or influence environment variables for the Skill process, such as through a compromised wrapper, CI configuration, container deployment, or service ...[truncated 1209 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove runtime control of the API origin unless it is strictly required. Prefer a fixed constant for https://api.jikeapi.cn.

  2. If endpoint configurability is necessary, parse the URL and enforce:

    • The https scheme.
    • An explicit allowlist of trusted hostnames.
    • An expected port.
    • No embedded user information.
    • No unexpected path prefix.
  3. Send the credential in an authorization header supported by the provider rather than in the query string, for example:

    python
    request = urllib.request.Request(url)
    request.add_header("Authorization", f"Bearer {appkey}")
    with urllib.request.urlopen(request, timeout=15) as response:
        ...
    

    If the provider only accepts an appkey query parameter, request header-based authentication support and ensure URLs are redacted from all logs and diagnostics in the interim.

  4. Remove the --key option for normal use and rely on protected environment or secret-management facilities. If it must remain for debugging, prominently warn that command-line secrets can appear in process listings and shell history.

  5. Ensure .env files containing credentials are excluded from source control and readable only by the intended account.

  6. Disable or carefully validate redirects for authenticated requests so credentials cannot be forwarded to an unexpected origin.

  7. Rotate any AppKey that may already have appeared in command history, process telemetry, proxy logs, or server logs.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (8)

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The request destination is derived from the JIKE_API_BASE_URL environment variable and then passed directly to urlopen. In an agent or multi-tenant runtime, a poisoned environment can redirect requests to an attacker-controlled host and exfiltrate the AppKey in the query string, creating an SSRF-style outbound request and credential leak.

Content

Scanner excerpt · scripts/calendar_holiday_query.py (reported line 138)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
60% confidence
Finding

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

Content

Scanner excerpt · scripts/calendar_holiday_query.py (reported line 53)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
91% confidence
Finding

The skill requires environment access for API keys and performs network requests, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates a least-privilege failure: an agent runtime may grant broader capabilities than users or policy reviewers expect, reducing transparency around secret access and outbound communication.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The description says the skill is suitable not only for holiday/date queries but also for '行情查询', which is unrelated and overly broad for the actual functionality. Overbroad triggers can cause the agent to invoke this skill in unintended contexts, leading to unnecessary external requests and disclosure of user query data to a third-party API.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The skill sends user-supplied date query information and an API credential to an external service at api.jikeapi.cn. Even though external access is expected for this integration, it is still a real data egress point and the example URL places the appkey in the query string, which increases exposure through logs, proxies, browser history, and monitoring systems.

Content

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

直接调用 API:

text
GET https://api.jikeapi.cn/v1/calendar/holiday/day?appkey=YOUR_APPKEY

AI 使用步骤

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": "支持查询某天是否放假或调休、某月假期、某年假期,返回假期名称、是否上班和调休目标日期。",
  "env": "JIKE_CALENDAR_HOLIDAY_QUERY_KEY",
  "api_url": "https://api.jikeapi.cn/v1/calendar/holiday/day",
  "homepage": "https://www.jikeapi.cn/"
}

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Natural-language strings throughout the file, including the module description, CLI help, and runtime output, force a specific language/locale. The policy allows locale constraints only when users are given a choice or the restriction is clearly documented and justified; neither appears here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The AppKey is appended to the URL query string, which commonly ends up in logs, proxies, browser history equivalents, monitoring systems, and server access logs. Even though HTTPS protects it in transit from passive observers, URL-based secrets have a much larger accidental exposure surface than headers or request bodies.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.