Back to skill

Security audit

宠物大全查询 - 聚合数据

Security checks for vulnerabilities and agentic risk

Overview

This is a straightforward Juhe pet lookup skill with some API-key handling cautions, but no hidden, destructive, or purpose-mismatched behavior was found.

Install only if you are comfortable sending pet search terms and your Juhe pet API key to Juhe. Prefer the environment variable method, avoid passing the key with --key, and if you use scripts/.env, keep it out of version control and restrict file permissions.

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/pet_query.py:65
Finding

API Credential Exposure Through URL Query Parameters and Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/pet_query.py:65-80, scripts/pet_query.py:115-123, and scripts/pet_query.py:294-297
Vulnerability Type: API credential exposure
Risk Level: Medium

Vulnerable Code

Search requests place the API key directly in the URL:

python
def search_pets(query: str = None, category: str = None, page: int = 1, page_size: int = 10, api_key: str = None) -> dict:
    """搜索宠物"""
    if not api_key:
        return {"success": False, "error": "未提供 API Key"}

    params = {
        "key": api_key,
        "page": page,
        "page_size": page_size,
    }
    if query:
        params["q"] = query
    if category:
        params["category"] = category

    data = urllib.parse.urlencode(params).encode("utf-8")
    url = f"{SEARCH_API_URL}?{urllib.parse.urlencode(params)}"

    try:
        with urllib.request.urlopen(url, timeout=10) as resp:
            result = json.loads(resp.read().decode("utf-8"))

Detail requests use the same credential transport pattern:

python
def get_pet_detail(hash_id: str, api_key: str = None) -> dict:
    """获取宠物详情"""
    if not api_key:
        return {"success": False, "error": "未提供 API Key"}

    params = {
        "key": api_key,
        "hash_id": hash_id,
    }
    url = f"{DETAIL_API_URL}?{urllib.parse.urlencode(params)}"

    try:
        with urllib.request.urlopen(url, timeout=10) as resp:
            result = json.loads(resp.read().decode("utf-8"))

The key can also be supplied as a command-line argument:

python
while i < len(args):
    if args[i] == "--key" and i + 1 < len(args):
        cli_key = args[i + 1]
        i += 2

Technical Analysis

The script transmits the Juhe API key in the query component of an HTTPS URL. HTTPS protects the complete request from passive network observers while it is in transit, but it does not prevent the URL fro ...[truncated 2833 chars]

Remediation
View remediation

Remediation Suggestions

  1. Prefer an API-supported authorization header rather than a query parameter, for example:

    python
    params = {
        "page": page,
        "page_size": page_size,
    }
    url = f"{SEARCH_API_URL}?{urllib.parse.urlencode(params)}"
    request = urllib.request.Request(
        url,
        headers={"Authorization": f"Bearer {api_key}"},
    )
    with urllib.request.urlopen(request, timeout=10) as resp:
        result = json.loads(resp.read().decode("utf-8"))
    

    The exact header and authentication scheme must match Juhe's official API specification.

  2. If Juhe mandates a key query parameter, clearly document this provider constraint and configure all application, proxy, monitoring, and access logging to redact the key parameter.

  3. Use a POST body only if the provider officially supports POST authentication. Do not assume that changing the request method is compatible with the API.

  4. Remove or strongly discourage --key. Prefer environment-based secret injection or a dedicated credential file with restrictive permissions. If command-line support must remain, display an explicit warning that the value may be stored in shell history and process telemetry.

  5. When .env is used, verify that it is excluded from version control and recommend owner-only permissions such as mode 0600 on systems that support POSIX permissions.

  6. Remove the unused encoded credential copy:

    python
    data = urllib.parse.urlencode(params).encode("utf-8")
    
  7. Ensure exception messages and diagnostics never print complete request URLs. Apply centralized redaction for parameter names such as key, token, and authorization.

  8. Rotate any API key suspected of having appeared in command history, telemetry, or URL logs, and review the provider's usage records for unexpected requests.

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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (11)

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The instructions recommend storing the API key in a local scripts/.env file, which is a common source of accidental credential exposure through commits, packaging, backups, or permissive file access. In a skill that performs external API calls, exposed keys can be abused for unauthorized requests, quota exhaustion, or billing impact.

Content

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

md
# 方式一:环境变量(推荐,一次配置永久生效)
export JUHE_PET_QUERY_KEY=你的 AppKey

# 方式二:.env 文件(在脚本目录创建)
echo "JUHE_PET_QUERY_KEY=你的 AppKey" > scripts/.env

# 方式三:每次命令行传入

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

The adjacent .env creation example operationalizes writing the secret directly into a file in the project tree, increasing the likelihood of inadvertent disclosure. Although the credential is only an API key, compromise still enables unauthorized third-party API usage and can leak behavioral metadata about how the skill is used.

Content

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

md
export JUHE_PET_QUERY_KEY=你的 AppKey

# 方式二:.env 文件(在脚本目录创建)
echo "JUHE_PET_QUERY_KEY=你的 AppKey" > scripts/.env

# 方式三:每次命令行传入
python scripts/pet_query.py --key 你的AppKey 哈士奇

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/pet_query.py (reported line 14)May include surrounding context.

python
API Key 配置(任选其一,优先级从高到低):
    1. 命令行参数:python pet_query.py --key your_api_key ...
    2. 环境变量:export JUHE_PET_QUERY_KEY=your_api_key
    3. 脚本同目录的 .env 文件:JUHE_PET_QUERY_KEY=your_api_key

免费申请 API Key: https://www.juhe.cn/docs/api/id/755
"""

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/pet_query.py (reported line 355)May include surrounding context.

python
API Key 配置(任选其一,优先级从高到低):
    1. 命令行参数:python pet_query.py --key your_api_key ...
    2. 环境变量:export JUHE_PET_QUERY_KEY=your_api_key
    3. 脚本同目录的 .env 文件:JUHE_PET_QUERY_KEY=your_api_key

免费申请 API Key: https://www.juhe.cn/docs/api/id/755
"""

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/pet_query.py (reported line 49)May include surrounding context.

python
if env_key:
        return env_key

    env_file = Path(__file__).parent / ".env"
    if env_file.exists():
        for line in env_file.read_text(encoding="utf-8").splitlines():
            line = line.strip()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares capabilities that imply environment-variable access, file reads, and outbound network use, but it does not declare any explicit tool scope or permissions boundary. This weakens least-privilege controls and can cause the runtime or user to underestimate what the skill can access, especially since it handles an API key and sends user queries to a third-party service.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description includes broad natural-language triggers like general pet questions and recommendations, which can cause the skill to activate for loosely related conversation. Overbroad triggering increases the chance that user content is sent to the external API unexpectedly, creating privacy and consent risks rather than direct code execution risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description does not clearly warn that the user's query text will be transmitted to the third-party Juhe API. Because pet names, preferences, or free-form queries may be user-provided content, the lack of disclosure undermines informed consent and can expose user data to an external service unexpectedly.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The natural-language interface, usage text, help text, and user-facing output are all written exclusively in Chinese, which imposes a locale/language constraint on users. There is no opt-in, fallback language, or documentation that this is intentionally a Chinese-only regional skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script places the API key in the URL query string when calling a third-party service. Even over HTTPS, query parameters are more likely to be exposed in logs, monitoring systems, browser/history equivalents, proxies, or diagnostic tooling, which increases the chance of credential disclosure. In this skill context, the key is intended for the external pet API, so the risk is real but limited to that service credential rather than local system compromise.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

技能名称、描述、示例和使用指南均以中文固定呈现,且没有说明是否支持其他语言或允许按用户语言偏好响应。若组织要求遵循用户语言/locale 偏好,这种默认单一语言设定可能构成自然语言策略不合规。

Content

No source excerpt is available for this finding.