Back to skill

Security audit

XiaomiYe

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real ecommerce-admin helper, but it needs review because it handles live store credentials, customer data, and business-changing actions while leaving important safeguards underspecified.

Install only for an authorized store-admin context. Use an HTTPS RR_CLAW_BASE_URL, keep the API key least-privileged, avoid shared long-running processes unless the client is tenant-scoped, confirm every business-changing action, and mask customer phone numbers, names, addresses, balances, and order details unless there is a clear business need to display them.

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

Error
Location
scripts/request_client.py:18
Finding

Bearer API credentials can be transmitted over unencrypted HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/request_client.py:18-35, 39-42, 54-63
Vulnerability Type: Missing HTTPS enforcement for authenticated API requests
Risk Level: High

Vulnerable Code

python
def __init__(
    self,
    base_url: str,
    api_key: str,
    timeout: int = 30,
) -> None:
    if not base_url:
        raise ValueError("base_url 不能为空")
    if not api_key:
        raise ValueError("api_key 不能为空")

    self.base_url = base_url
    self.api_key = api_key
    self.timeout = timeout

    self.session = requests.Session()
    self.session.headers.update({
        "Authorization": f"Bearer {self.api_key}",
    })

def _build_url(self, path: str) -> str:
    base_url = self.base_url.rstrip("/")
    path = path.lstrip("/")
    return f"{base_url}/{path}"

The resulting URL is used without scheme validation:

python
url = self._build_url(path)
response = self.session.request(
    method,
    url,
    params=params,
    data=data,
    json=json,
    timeout=self.timeout,
    **kwargs,
)

Technical Analysis

The client accepts any non-empty base_url and unconditionally attaches a bearer API key to its session. It does not parse the URL or require the HTTPS scheme. Consequently, an http:// base URL is accepted and the Authorization header is transmitted without transport encryption.

Restricting requests to a user-configured destination does not provide confidentiality or server authenticity. Plain HTTP allows an attacker with a suitable network position to observe or modify traffic. The problem affects every authenticated query and mutation exposed by the client.

Attack Path

  1. A merchant or platform configuration supplies an RR_CLAW_BASE_URL beginning with http://, whether through error, insecure deployment guidance, or configuration tampering.
  2. RequestClient.__init__ accepts the value because it only checks whether it is empty.
  3. The client stores the API key in the session-wide `Authorizat ...[truncated 1032 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse base_url with urllib.parse.urlsplit during initialization.
  2. Reject every scheme except https.
  3. Reject URLs containing embedded usernames or passwords.
  4. Require a valid hostname and reject malformed or ambiguous URLs.
  5. If local HTTP development is necessary, require an explicit development-only option and restrict it to loopback addresses such as 127.0.0.1 and ::1.
  6. Keep TLS certificate verification enabled and do not permit callers to override it through unrestricted request keyword arguments.
  7. Add tests confirming that HTTP, scheme-relative, credential-bearing, and malformed URLs are rejected.
  8. Document HTTPS as mandatory for RR_CLAW_BASE_URL.

Example hardening:

python
from urllib.parse import urlsplit

parsed = urlsplit(base_url)
if parsed.scheme.lower() != "https":
    raise ValueError("base_url must use HTTPS")
if not parsed.hostname:
    raise ValueError("base_url must contain a valid hostname")
if parsed.username is not None or parsed.password is not None:
    raise ValueError("base_url must not contain embedded credentials")

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/request_client.py:104
Finding

Process-global API client can cause cross-tenant credential and destination reuse

Content
View full analysis

Vulnerability Details

File Location: scripts/request_client.py:104-120
Vulnerability Type: Unsafe global authentication state and silent configuration reuse
Risk Level: Medium

Vulnerable Code

python
_client: Optional[RequestClient] = None


def get_client(
    base_url: Optional[str] = None,
    api_key: Optional[str] = None,
    timeout: int = 30,
) -> RequestClient:
    """
    获取全局 RequestClient 单例。
    首次调用时必须传入 base_url 和 api_key 以完成初始化;后续调用可省略参数直接复用。
    """
    global _client
    if _client is None:
        if not base_url or not api_key:
            raise ValueError("首次调用 get_client() 必须提供 base_url 和 api_key")
        _client = RequestClient(base_url, api_key, timeout)
    return _client

Technical Analysis

The module stores one authenticated RequestClient in process-global state. After the first initialization, all subsequent calls return that object. Any later base_url, api_key, or timeout arguments are silently ignored.

This design is unsafe when the module is used by a long-lived worker, concurrent agent runtime, test process, or any environment that serves more than one merchant. The first caller’s destination and bearer credential remain active for the process lifetime. A later caller can therefore issue operations against the first caller’s store even when it supplies its own configuration.

The confirmation requirements documented for destructive operations reduce accidental invocation but do not establish tenant isolation: a correctly confirmed action can still be sent to the wrong merchant account.

Attack Path

  1. Merchant A initializes get_client() with A’s base URL and API key.
  2. The resulting authenticated client is retained in the module-level _client variable.
  3. The same Python process later handles Merchant B.
  4. Merchant B calls get_client() with B’s base URL and API key, or calls it without arguments as documented.
  5. The function silently returns Merchant A’s existing client.

...[truncated 1062 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the process-global singleton and construct a separate RequestClient for each execution or caller.
  2. Pass the client explicitly to code that performs API operations.
  3. If connection reuse is necessary, scope cached clients to an authenticated tenant or request context rather than the entire process.
  4. Store tenant-specific clients in context-local state and ensure cleanup after each task.
  5. Never silently ignore supplied credentials or endpoint settings. If singleton behavior must remain, reject conflicting reinitialization.
  6. Avoid retaining API keys longer than necessary.
  7. Add isolation tests that initialize two merchant configurations in one process and verify that each request reaches only its intended endpoint.

A safer factory is:

python
def get_client(
    base_url: str,
    api_key: str,
    timeout: int = 30,
) -> RequestClient:
    return RequestClient(base_url, api_key, timeout)

If compatibility requires a singleton, fail closed on conflicting configuration:

python
if _client is not None:
    if base_url and base_url.rstrip("/") != _client.base_url.rstrip("/"):
        raise RuntimeError("Client is already initialized for another endpoint")
    if api_key and api_key != _client.api_key:
        raise RuntimeError("Client is already initialized with another credential")
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (16)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill performs network operations against a user-configured商城 API endpoint but does not declare any explicit tool scope such as permissions or allowed-tools. Without an explicit scope boundary, a host platform may grant broader network capability than reviewers or users expect, increasing the chance of unintended outbound requests or misuse if the skill is modified or interpreted loosely.

Content

No source excerpt is available for this finding.

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/goods.md (reported line 22)May include surrounding context.

md
**请求参数:**

| 字段        | 类型     | 必传 | 说明                                                                                                                                |
|-----------|--------|----|-----------------------------------------------------------------------------------------------------------------------------------|
| keywords  | string | 否  | 搜索关键字(可匹配商品标题、编码、条码)                                                                                                              |
| type      | int    | 否  | 商品类型:`0` 实体商品 / `1` 虚拟商品 / `2` 虚拟卡密 / `3` 预约到店 / `5` 计次时商品 / `8` 批发商品 / `9` 智慧药房 / `13` 海淘商品 / `20` 社区团购 / `21` 期刊商品 / `22` 供应链商品 |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/goods.md (reported line 24)May include surrounding context.

md
| 字段        | 类型     | 必传 | 说明                                                                                                                                |
|-----------|--------|----|-----------------------------------------------------------------------------------------------------------------------------------|
| keywords  | string | 否  | 搜索关键字(可匹配商品标题、编码、条码)                                                                                                              |
| type      | int    | 否  | 商品类型:`0` 实体商品 / `1` 虚拟商品 / `2` 虚拟卡密 / `3` 预约到店 / `5` 计次时商品 / `8` 批发商品 / `9` 智慧药房 / `13` 海淘商品 / `20` 社区团购 / `21` 期刊商品 / `22` 供应链商品 |
| status    | int    | 否  | 商品状态:不传=全部 / `1` 上架 / `2` 售罄 / `3` 下架 / `4` 已删除                                                                                   |
| sort      | string | 否  | 排序字段:`real_sales` 真实销量 / `create_time` 创建时间                                                                                       |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/goods.md (reported line 26)May include surrounding context.

md
|-----------|--------|----|-----------------------------------------------------------------------------------------------------------------------------------|
| keywords  | string | 否  | 搜索关键字(可匹配商品标题、编码、条码)                                                                                                              |
| type      | int    | 否  | 商品类型:`0` 实体商品 / `1` 虚拟商品 / `2` 虚拟卡密 / `3` 预约到店 / `5` 计次时商品 / `8` 批发商品 / `9` 智慧药房 / `13` 海淘商品 / `20` 社区团购 / `21` 期刊商品 / `22` 供应链商品 |
| status    | int    | 否  | 商品状态:不传=全部 / `1` 上架 / `2` 售罄 / `3` 下架 / `4` 已删除                                                                                   |
| sort      | string | 否  | 排序字段:`real_sales` 真实销量 / `create_time` 创建时间                                                                                       |
| by        | string | 否  | 排序方式:`asc` 升序 / `desc` 降序                                                                                                         |
| page      | int    | 否  | 页码(默认 1)                                                                                                                          |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/goods.md (reported line 27)May include surrounding context.

md
| keywords  | string | 否  | 搜索关键字(可匹配商品标题、编码、条码)                                                                                                              |
| type      | int    | 否  | 商品类型:`0` 实体商品 / `1` 虚拟商品 / `2` 虚拟卡密 / `3` 预约到店 / `5` 计次时商品 / `8` 批发商品 / `9` 智慧药房 / `13` 海淘商品 / `20` 社区团购 / `21` 期刊商品 / `22` 供应链商品 |
| status    | int    | 否  | 商品状态:不传=全部 / `1` 上架 / `2` 售罄 / `3` 下架 / `4` 已删除                                                                                   |
| sort      | string | 否  | 排序字段:`real_sales` 真实销量 / `create_time` 创建时间                                                                                       |
| by        | string | 否  | 排序方式:`asc` 升序 / `desc` 降序                                                                                                         |
| page      | int    | 否  | 页码(默认 1)                                                                                                                          |
| page_size | int    | 否  | 每页数量(默认 6)                                                                                                                        |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/goods.md (reported line 28)May include surrounding context.

md
| type      | int    | 否  | 商品类型:`0` 实体商品 / `1` 虚拟商品 / `2` 虚拟卡密 / `3` 预约到店 / `5` 计次时商品 / `8` 批发商品 / `9` 智慧药房 / `13` 海淘商品 / `20` 社区团购 / `21` 期刊商品 / `22` 供应链商品 |
| status    | int    | 否  | 商品状态:不传=全部 / `1` 上架 / `2` 售罄 / `3` 下架 / `4` 已删除                                                                                   |
| sort      | string | 否  | 排序字段:`real_sales` 真实销量 / `create_time` 创建时间                                                                                       |
| by        | string | 否  | 排序方式:`asc` 升序 / `desc` 降序                                                                                                         |
| page      | int    | 否  | 页码(默认 1)                                                                                                                          |
| page_size | int    | 否  | 每页数量(默认 6)                                                                                                                        |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/goods.md (reported line 29)May include surrounding context.

md
| status    | int    | 否  | 商品状态:不传=全部 / `1` 上架 / `2` 售罄 / `3` 下架 / `4` 已删除                                                                                   |
| sort      | string | 否  | 排序字段:`real_sales` 真实销量 / `create_time` 创建时间                                                                                       |
| by        | string | 否  | 排序方式:`asc` 升序 / `desc` 降序                                                                                                         |
| page      | int    | 否  | 页码(默认 1)                                                                                                                          |
| page_size | int    | 否  | 每页数量(默认 6)                                                                                                                        |

**响应字段:**

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · references/goods.md (reported line 30)May include surrounding context.

md
| sort      | string | 否  | 排序字段:`real_sales` 真实销量 / `create_time` 创建时间                                                                                       |
| by        | string | 否  | 排序方式:`asc` 升序 / `desc` 降序                                                                                                         |
| page      | int    | 否  | 页码(默认 1)                                                                                                                          |
| page_size | int    | 否  | 每页数量(默认 6)                                                                                                                        |

**响应字段:**

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

顶部接口总览将“会员详情”标注为 GET /member/list/get,但后文正式章节将会员详情接口定义为 GET /member/detail/get。这是文档内部对同一能力的主动性矛盾,可能导致调用方误用列表接口获取详情。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill documents an endpoint that lets an operator derive a member ID directly from a phone number and elsewhere exposes rich member PII such as real name, mobile number, balance, birthday, and account metadata, but provides no privacy constraints, masking guidance, authorization requirements, or data-minimization warnings. In the context of a shopping/admin assistant, this materially increases the risk of user enumeration, privacy abuse, and overexposure of sensitive customer data if the skill is used by overprivileged operators or integrated into broad conversational workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The example API responses include real-world-style personal data fields such as recipient name, mobile number, real name, and address without masking or an explicit privacy warning. Even if the values are illustrative, publishing unredacted PII patterns in documentation normalizes unsafe handling of sensitive customer data and can lead downstream agents or operators to expose, log, or reuse such fields improperly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The example response includes a full mobile phone number without masking or any privacy warning, which normalizes exposure of personally identifiable information in documentation and downstream implementations. Because this skill is intended for operational querying of member data, developers may replicate this behavior in UIs, logs, and prompts, increasing the risk of privacy leakage.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

该技能文档从标题到全部接口说明均仅以中文呈现,未见任何可选语言、locale 适用范围或仅限中文用户的说明。按规则,强制单一语言而无用户选择或明确合理化,属于自然语言层面的语言/locale 政策问题。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The file presents all user-facing documentation in Chinese and does not offer an alternative language option or explain that the skill is intended for a Chinese-speaking or region-specific audience. Per the policy criteria, forcing a specific language without user opt-in can be a natural-language policy violation when no justification or choice is documented.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The member-ranking field documentation omits a sensitive field that appears in the example response (mobile), creating a mismatch between documented and actual data exposure. In a data-query/order-management skill, this can mislead integrators into handling responses less carefully and cause unintended collection, display, or logging of personal data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The exception and class docstrings are written entirely in Chinese, including user-visible error descriptions such as the APIError message context. This suggests a language-specific behavior or documentation expectation without any indication that the skill supports user language choice or is intentionally limited to a Chinese-only environment.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.