Back to skill

Security audit

TikTok官方-店铺履约

Security checks for vulnerabilities and agentic risk

Overview

The skill is a legitimate TikTok Shop fulfillment helper, but it exposes broader API proxy authority than its narrow split-attributes purpose suggests.

Review before installing. Use this only in a controlled environment with a trusted LinkFox gateway configuration, a narrowly scoped API key, and explicit human approval for any use of fulfillment_proxy.py. Prefer the named read-only get_order_split_attributes flow and avoid passing arbitrary paths, methods, or request bodies unless you intend to grant broader TikTok Shop ERP authority.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/_fulfillment_api_runner.py:259
Finding
Generic fulfillment proxy permits operations beyond the Skill's read-only purpose<![CDATA[ ## Vulnerability Details **File Location**: `scripts/_fulfillment_api_runner.py:259-297`; related validation in `scripts/_shop_fulfillment_common.py:110-149` **Vulnerability Type**: T05: Unauthorized Access and Privilege Escalation **Risk Level**: Medium ### Vulnerable Code ```python def run_fulfillment_proxy(params: dict, caller: str = "fulfillment_proxy.py") -> dict: """Generic proxy: path + method + openId (+ optional shop_cipher).""" if not params.get("skipDepCheck"): ensure_auth_skill_available(caller) path = params.get("path") method = params.get("method") if not path or not method: print("Missing required fields: path, method", file=sys.stderr) sys.exit(1) open_id = require_open_id(params) shop_cipher = None needs_cipher = str(path).lstrip("/").startswith("fulfillment/") if needs_cipher: shop_cipher = resolve_shop_cipher(params, open_id) query_string = params.get("queryString") if shop_cipher: pairs = dict(parse_qsl(str(query_string or "").lstrip("?"), keep_blank_values=True)) pairs["shop_cipher"] = shop_cipher query_string = urlencode(pairs) body = params.get("body") if body is not None and not isinstance(body, str): body = json.dumps(body, ensure_ascii=False, separators=(",", ":")) if "requestBody" in params and body is None: rb = params["requestBody"] body = rb if isinstance(rb, str) else json.dumps(rb, ensure_ascii=False, separators=(",", ":")) proxy = developer_proxy_call( open_id, str(path), str(method).upper(), region=params.get("region"), query_string=query_string, body=body, content_type=str(params.get("contentType") or "application/json"), ) ``` The applicable path validation is: ```python def assert_path_allowed(path: str) -> None: normalized = path.lstrip("/").replace("\\", "/") if ".." in normalized or "//" in normali ...[truncated 3436 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove or disable the generic proxy for the current read-only Skill. 2. Enforce an exact allowlist of method and path pairs: - `GET authorization/202309/shops` - `GET fulfillment/202309/orders/split_attributes` 3. Reject all methods other than those explicitly registered for each endpoint. 4. Validate query parameters and bodies against endpoint-specific schemas rather than accepting arbitrary data. 5. Maintain separate read-only and mutation-capable tools if future fulfillment operations are added. 6. Require explicit user confirmation before every state-changing operation. 7. Apply equivalent endpoint and method restrictions at the LinkFox gateway so client-side checks are not the sole security boundary. 8. Use narrowly scoped TikTok application permissions and seller tokens wherever the platform supports them. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shop_fulfillment_common.py:15
Finding
Environment-controlled gateway can receive API credentials and shop data without transport validation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/_shop_fulfillment_common.py:15-20, 59-84` **Vulnerability Type**: T09: Insecure Skill Coding Practices **Risk Level**: Medium ### Vulnerable Code ```python API_BASE_URL = ( os.environ.get("LINKFOX_TOOL_GATEWAY") or os.environ.get("TIKTOK_SHOP_API_BASE_URL") or "https://tool-gateway.linkfox.com" ).rstrip("/") DEVELOPER_PROXY_ENDPOINT = f"{API_BASE_URL}/tiktokShop/developerProxy" ``` ```python def get_api_key() -> str: key = os.environ.get("LINKFOX_AGENT_API_KEY") or os.environ.get("LINKFOXAGENT_API_KEY") if not key: print("API Key 未配置", file=sys.stderr) sys.exit(1) return key def call_api(endpoint: str, params: dict) -> dict: api_key = get_api_key() data = json.dumps(params).encode("utf-8") req = Request( endpoint, data=data, headers={ "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/1.0", "SESSION_ID": os.environ.get("SESSION_ID", ""), "MODE_ID": os.environ.get("MODE_ID", ""), "APP_NAME": os.environ.get("APP_NAME", ""), }, method="POST", ) try: with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` ### Technical Analysis The Skill permits `LINKFOX_TOOL_GATEWAY` or `TIKTOK_SHOP_API_BASE_URL` to replace the default LinkFox gateway. The replacement URL is not validated for: - An HTTPS scheme. - A trusted hostname. - An approved port. - Embedded user information. - An expected URL structure. Every request to the resulting endpoint includes the LinkFox API key in the `Authorization` header. It also transmits `SESSION_ID`, `MODE_ID`, and `APP_NAME`, plus a request body that can contain seller `openId`, shop cipher, order IDs, query parameters, and fulfillment request bodies. Sending this information to the documented defau ...[truncated 1792 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require the gateway URL to use `https`. 2. Parse the configured URL with a standard URL parser and reject: - Non-HTTPS schemes. - Embedded usernames or passwords. - Unexpected ports. - Fragments or malformed paths. 3. Enforce an explicit hostname allowlist, with `tool-gateway.linkfox.com` as the default approved destination. 4. If custom gateways are operationally necessary, require an explicit administrator-controlled opt-in and use a separate, narrowly scoped credential for each gateway. 5. Do not attach the production LinkFox API key to untrusted or arbitrary destinations. 6. Remove `SESSION_ID`, `MODE_ID`, and `APP_NAME` from outbound requests unless each field is documented as necessary. 7. Use scoped, short-lived, and revocable API credentials where supported. 8. Apply outbound network policy controls so the runtime can connect only to approved API hosts. 9. Avoid returning or logging raw upstream error bodies when they may contain sensitive operational data. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (26)

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

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""
Confidence
93% confidence
Finding
The outbound request target is derived from environment-controlled `API_BASE_URL`, and the request includes sensitive headers such as the API key plus session/mode/app identifiers. If an attacker can influence environment variables, they can redirect requests to an arbitrary host and exfiltrate credentials and identifiers; in this skill context, that is more serious because the code is a proxy helper for TikTok Shop ERP operations and carries privileged integration metadata.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill explicitly says it does not include authorization, but the documented proxy scope allows authorization/ paths and arbitrary method/path forwarding within whitelisted prefixes. That inconsistency can permit access to sensitive authorization-related data or flows under a misleading non-auth label.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill explicitly says it does not include authorization, but the documented proxy scope allows authorization/ paths and arbitrary method/path forwarding within whitelisted prefixes. That inconsistency can permit access to sensitive authorization-related data or flows under a misleading non-auth label.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill explicitly says it does not include authorization, but the documented proxy scope allows authorization/ paths and arbitrary method/path forwarding within whitelisted prefixes. That inconsistency can permit access to sensitive authorization-related data or flows under a misleading non-auth label.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill explicitly says it does not include authorization, but the documented proxy scope allows authorization/ paths and arbitrary method/path forwarding within whitelisted prefixes. That inconsistency can permit access to sensitive authorization-related data or flows under a misleading non-auth label.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
}'
```

## Display Rules

1. 勿输出完整 accessToken。
2. 优先展示每个 `order_id` 的 `can_split` / `must_split` / `reason` / `must_split_reasons`。
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
This file documents and wires an authorization-related API (`get_authorized_shops`) inside a skill whose declared scope explicitly excludes authorization and is limited to fulfillment split-attributes. That scope mismatch can cause the agent to expose or invoke shop-authorization listing functionality unexpectedly, enabling enumeration of authorized shops and retrieval of shop ciphers beyond the user-expected permission boundary.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The skill metadata says this capability is for Get Order Split Attributes, but run_fulfillment_proxy accepts arbitrary path and method values and forwards them through the ERP developer proxy. That creates a broader-than-declared API surface, allowing callers to reach other fulfillment endpoints and potentially perform unintended reads or state-changing actions with the user's ERP authorization context.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
This code provides an unjustifiably broad proxy primitive for a narrowly scoped split-attributes skill: any caller who can supply path and method can drive the backend proxy to unadvertised ERP fulfillment APIs. In this context, the mismatch between the manifest scope and the implementation is especially dangerous because users and higher-level agents may trust the skill as read-only or limited while it can access additional data or invoke operations behind the scenes.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The script explicitly advertises and permits proxying of authorization/ paths despite the manifest stating that authorization is not included and should be handled by a separate skill. Exposing authorization-related routing in this skill can allow token, shop-selection, or other auth-adjacent operations through an unintended entry point, creating privilege-boundary confusion and increasing the chance of account takeover, token misuse, or bypass of intended workflow controls.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill documentation exposes executable capabilities and networked proxy behavior but does not declare any explicit tool scope or allowed-tools constraints. In an agent environment, that means the runtime may permit broader shell, env, or network access than users or orchestrators expect, increasing the blast radius if the skill is misused or prompt-injected.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The documentation says the skill excludes authorization, yet the proxy whitelist includes authorization/ endpoints. This creates a deceptive trust boundary: operators may approve the skill as non-auth-related while it still has reach into authorization functions and data paths.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The document body is written in Chinese while the title and surrounding repository context are not explicitly region- or language-specific. This creates a natural-language locale policy issue because the skill documentation effectively requires Chinese comprehension without offering an opt-in language choice or documenting a justified locale restriction.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
Labeling the authorization API mapping as belonging to '本 skill' is dangerous because it normalizes an out-of-scope capability inside the fulfillment skill and may mislead the agent or maintainers into treating authorization data access as intended behavior. In this context, the skill metadata explicitly says it does not include authorization, so the contradictory documentation increases the likelihood of unauthorized data access through prompt/tool selection confusion.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
Because `developer_proxy_call` accepts an arbitrary allowed path and the whitelist includes the broad `authorization` prefix, the helper can proxy a wider set of authorization API calls than justified for a split-attributes fulfillment skill. In context, this expands capability beyond the declared purpose and increases the blast radius if higher-level code passes attacker-influenced paths or if the skill is repurposed.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The whitelist explicitly allows `authorization` paths even though the skill metadata says the skill does not include authorization behavior. That scope mismatch weakens least-privilege boundaries and enables this fulfillment helper to reach auth-related proxy endpoints that users and reviewers would not expect.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
print(f"DEPENDENCY_MISSING: {json.dumps(payload, ensure_ascii=False)}", file=sys.stderr)
        sys.exit(DEPENDENCY_EXIT_CODE)
    try:
        result = subprocess.run(
            [sys.executable, str(checker)],
            capture_output=True,
            text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
The code reads LINKFOX_AGENT_API_KEY from the environment and then uses it as an Authorization header in a network request. Accessing sensitive credentials and transmitting them externally should have some visible disclosure, but this file only emits an error when the key is missing and does not warn about its use.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The HTTP request includes SESSION_ID, MODE_ID, and APP_NAME headers sourced from environment variables, which transmits user or system context to an external endpoint. Although the code performs the network call, there is no confirmation prompt or explicit user-facing notice here that these environment-derived values will be sent.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The wrapper accepts a caller-supplied JSON blob and forwards it to a generic fulfillment proxy with only a documented prefix whitelist, which is materially broader than the skill’s declared purpose of querying split attributes. That mismatch creates an overbroad capability surface: a user or downstream component can invoke additional Fulfillment or Authorization endpoints not intended by the manifest, weakening least-privilege and enabling unauthorized business actions or data access if the backend runner honors those paths.

Intent-Code Divergence

Medium
Confidence
88% confidence
Finding
Describing the module as a generic path/method proxy signals and likely reflects an implementation that is broader than the narrowly documented split-attributes use case. In security-sensitive integrations, this kind of capability/documentation mismatch is dangerous because operators, reviewers, and policy layers may assume a read-only single-endpoint skill while the code exposes a reusable proxy primitive that can be repurposed for unintended API calls.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The script's behavior does not match the declared skill purpose: instead of querying order split attributes, it performs authorized-shop discovery. This creates an undeclared capability that can expose shop inventory/tenancy information and mislead upstream systems or reviewers about what data the skill accesses.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
Authorized-shop enumeration is not justified by a skill scoped to fulfillment split-attribute checks, so it broadens access beyond the user's apparent request. In this context, shop discovery can leak which shops are linked to an openId and enable unnecessary cross-tenant reconnaissance or targeting if invoked by an attacker or misused by an agent.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
The 'Agent 注意事项' instructions tell the agent how to respond to users in Chinese, including explaining reasons and split requirements, but do not indicate that the user's preferred language should be used. This creates a natural-language locale policy concern because the skill implicitly fixes response language without opt-in or documented justification.

Natural-Language Policy Violations

Low
Confidence
96% confidence
Finding
The hardcoded message "API Key 未配置" is a Chinese-only user-facing string. The file does not offer language selection or explain that the skill is intentionally limited to a Chinese-language locale, which can violate language/locale policy requirements.

Static analysis

No suspicious patterns detected.