Back to skill

Security audit

TikTok官方-店铺物流仓库

Security checks for vulnerabilities and agentic risk

Overview

The skill is mainly for TikTok Shop warehouse lookups, but it exposes broader proxy access than its stated scope.

Review this before installing. It is not evidence of malware, but it can use LinkFox/TikTok credentials through a broad developer proxy, includes authorization-shop lookup despite saying authorization is out of scope, and allows gateway URL overrides. Install only if you trust the publisher, understand the LinkFox gateway controls, and are comfortable with the broader logistics/authorization API reach.

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

Error
Location
scripts/_logistics_api_runner.py:258
Finding
Generic ERP proxy exceeds the Skill's declared read-only scope<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/_shop_logistics_common.py:25` - `scripts/_shop_logistics_common.py:108-122` - `scripts/_logistics_api_runner.py:258-308` - `scripts/logistics_proxy.py:12-20` **Vulnerability Type**: Excessive API authorization scope and insufficient endpoint/method restrictions **Risk Level**: High ### Vulnerable Code ```python # scripts/_shop_logistics_common.py:25 ALLOWED_PATH_PREFIXES = ("logistics", "authorization") ``` ```python # scripts/_shop_logistics_common.py:108-122 def assert_path_allowed(path: str) -> None: normalized = path.lstrip("/").replace("\\", "/") if ".." in normalized or "//" in normalized: print(f"Error: invalid path {path!r}", file=sys.stderr) sys.exit(1) if not any( normalized == prefix or normalized.startswith(prefix + "/") for prefix in ALLOWED_PATH_PREFIXES ): print( f"Error: path must start with one of {ALLOWED_PATH_PREFIXES}, got {path!r}", file=sys.stderr, ) sys.exit(1) ``` ```python # scripts/_logistics_api_runner.py:258-308 def run_logistics_proxy(params: dict, caller: str = "logistics_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("logistics/") 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(pair ...[truncated 3981 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `logistics_proxy.py` if generic proxy functionality is not essential to the declared Skill. 2. Replace namespace-prefix validation with an exact endpoint and method allowlist: - `GET authorization/202309/shops` - `GET logistics/202309/warehouses` 3. Reject all request bodies for these two GET endpoints. 4. Reject unsupported query fields instead of forwarding arbitrary `queryString` values. 5. Validate methods before sending requests and permit only methods explicitly registered for each path. 6. Enforce the same endpoint/method allowlist at the LinkFox gateway so bypassing the local wrapper cannot grant additional access. 7. Separate any future state-changing APIs into independently reviewed capabilities with explicit user confirmation and narrowly scoped authorization. 8. Add automated negative tests proving that unregistered paths and `POST`, `PUT`, `PATCH`, and `DELETE` requests are rejected. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shop_logistics_common.py:15
Finding
Sensitive credentials and seller identifiers can be redirected to an unvalidated gateway<![CDATA[ ## Vulnerability Details **File Location**: `scripts/_shop_logistics_common.py:15-20, 59-86, 128-148` **Vulnerability Type**: Unvalidated outbound destination for sensitive authentication and seller data **Risk Level**: Medium ### Vulnerable Code ```python # scripts/_shop_logistics_common.py:15-20 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 # scripts/_shop_logistics_common.py:59-86 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")) except HTTPError as e: body = e.read().decode("utf-8") if e.fp else "" return {"error": f"HTTP {e.code}: {e.reason}", "details": body} except URLError as e: return {"error": f"Connection failed: {e.reason}"} ``` ```python # scripts/_shop_logistics_common.py:128-148 def developer_proxy_call( open_id: str, path: str, method: str, region: Optional[str] = None, query_string: Optional[str] = None, body: Optional[str] = None, content_type: str = "application/json", ) -> dict: assert_path_allowed(path) proxy: dict[str, Any] = { "path": path.lstrip("/"), "method": method, "openId": open_id, "appType": ERP_APP_TYPE, } ...[truncated 2883 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require HTTPS for all gateway URLs and reject `http://` or any non-HTTPS scheme. 2. Allowlist approved gateway hostnames, preferably only `tool-gateway.linkfox.com`. 3. If custom gateways are operationally necessary, require an explicit secure opt-in and maintain a configurable hostname allowlist. 4. Validate the parsed URL before constructing the endpoint: - Scheme must be `https`. - Hostname must exactly match an approved host. - Reject embedded credentials, fragments, unexpected ports, and malformed URLs. 5. Do not reuse the production LinkFox API key for custom gateway destinations. Use separate, narrowly scoped credentials. 6. Send `SESSION_ID`, `MODE_ID`, and `APP_NAME` only if the gateway requires them; otherwise remove those headers. 7. Apply least-privilege scopes, expiration, and rotation to the LinkFox API key. 8. Add tests confirming that attacker-controlled hosts, plaintext URLs, user-info URLs, and hostname-suffix tricks are rejected. ]]>
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (29)

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
97% confidence
Finding
The outbound request target is derived from environment-controlled base URL settings, and the request includes sensitive credentials and context headers such as the API key, SESSION_ID, MODE_ID, and APP_NAME. If an attacker can influence LINKFOX_TOOL_GATEWAY or TIKTOK_SHOP_API_BASE_URL, the skill can be turned into an SSRF/exfiltration primitive that sends secrets to an attacker-controlled endpoint.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documented proxy supports arbitrary logistics paths/methods and even authorization/ paths, despite the skill claiming to exclude authorization and non-warehouse functions. In an agentic setting, arbitrary forwarding through a trusted gateway can become a confused-deputy path to broader API access than users or orchestrators intended.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented proxy supports arbitrary logistics paths/methods and even authorization/ paths, despite the skill claiming to exclude authorization and non-warehouse functions. In an agentic setting, arbitrary forwarding through a trusted gateway can become a confused-deputy path to broader API access than users or orchestrators intended.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The documented proxy supports arbitrary logistics paths/methods and even authorization/ paths, despite the skill claiming to exclude authorization and non-warehouse functions. In an agentic setting, arbitrary forwarding through a trusted gateway can become a confused-deputy path to broader API access than users or orchestrators intended.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented proxy supports arbitrary logistics paths/methods and even authorization/ paths, despite the skill claiming to exclude authorization and non-warehouse functions. In an agentic setting, arbitrary forwarding through a trusted gateway can become a confused-deputy path to broader API access than users or orchestrators intended.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
python scripts/logistics_api.py '{"api":"get_warehouse_list","openId":"...","shop_cipher":"GCP_..."}'
```

## Display Rules

1. 勿输出完整 accessToken。
2. 列表优先展示:`id`、`name`、`type`、`sub_type`、`effect_status`、`is_default`、地址摘要。
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
The function run_logistics_proxy implements a generic forwarding primitive that accepts arbitrary path and method values and sends them through the ERP developer proxy. That exceeds the skill’s declared warehouse-list scope and can be used to invoke other logistics endpoints, including future or undocumented operations, turning a narrowly scoped skill into a broad API broker.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
This code exposes arbitrary API forwarding even though the skill metadata says it is only for Get Warehouse List. In practice, a caller can supply custom path, method, query string, and body, which bypasses the endpoint registry safety model used by run_logistics_api and enables unauthorized expansion of capability within the same authenticated context.

Lp3

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding
The skill documentation describes executable scripts and networked proxy access, but it does not declare any explicit tool scope or allowed-tools boundary. In an agent environment, undocumented shell/network/env capabilities increase the chance of over-privileged execution and make it harder to constrain what the skill may do.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The activation description says the skill triggers when users mention terms including generic phrases like '仓库列表' and '查店铺仓库'. In a manifest/markdown trigger description, these phrases are broad enough to overlap with ordinary discussion of warehouse information, and the file does not provide negative examples or stricter scope constraints beyond the product domain.

Description-Behavior Mismatch

Medium
Confidence
86% confidence
Finding
The documentation says the skill is limited to warehouse-list logistics use, but the stated proxy scope includes authorization paths and generic forwarding parameters. Security-sensitive documentation inconsistencies matter because operators may grant trust based on the narrow description while the actual interface is broader.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
This file documents and appears to wire an authorization-scope API (`get_authorized_shops`) into a skill घोषित as logistics-only and explicitly non-authorization. That scope mismatch can expose shop inventory/account linkage data and `shop cipher` values to workflows or callers that should only access warehouse data, increasing the chance of confused-deputy access and accidental data disclosure.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
Labeling the authorization endpoint mapping as '本 skill' materially contradicts the metadata saying this skill does not handle authorization. That inconsistency can cause an agent or integrator to invoke the wrong capability under a trusted logistics label, enabling unauthorized shop discovery or downstream use of returned identifiers.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The documentation states that the API retrieves authorized shops and obtains the corresponding shop cipher, but gives no warning that this returns sensitive account/shop linkage information. In an agent setting, absence of sensitivity labeling increases the risk that these values are surfaced, logged, or reused in later calls without appropriate user awareness or least-privilege controls.

Intent-Code Divergence

Medium
Confidence
87% confidence
Finding
The docstring explicitly labels this as a generic proxy while the manifest describes a narrow warehouse-list skill. That mismatch is a strong indicator of scope drift and makes it easier for maintainers or downstream agents to misuse the skill as a broader logistics API tunnel than users or policy expect.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest says this logistics skill is limited to Logistics Open API warehouse listing and explicitly states '**不含授权**(用 linkfox-tiktok-shop-auth)'. However, the registry exposes a `get_authorized_shops` endpoint under this skill, which is an authorization/shop-selection capability rather than warehouse-list retrieval. This exceeds the described behavior of a logistics-only warehouse-list skill.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The code exposes authorization API access that is not justified by the stated warehouse/logistics purpose, increasing available attack surface for a skill that should only handle warehouse listing. In the context of an ERP logistics skill, unnecessary authorization reach is more dangerous because it may enable token/account-related operations under the same openId-based proxy flow.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The helper explicitly allowlists the authorization path prefix even though the skill description says this logistics skill does not include authorization behavior. This creates a capability mismatch: any script reusing this helper can access authorization endpoints through developerProxy, expanding the skill beyond its declared scope and weakening least-privilege boundaries.

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
90% confidence
Finding
The request forwards SESSION_ID, MODE_ID, and APP_NAME to the remote gateway without any minimization or visible justification in this file. These identifiers may be sensitive operational metadata, and combined with the environment-configurable endpoint they increase the risk of user/context leakage to unintended services.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest says this logistics skill forwards only the Get Warehouse List API and explicitly frames itself around warehouse listing. This file instead documents and invokes a different operation, `get_authorized_shops`, to fetch `shop_cipher`, which is a shop-authorization/discovery capability rather than warehouse listing.

Intent-Code Divergence

Medium
Confidence
87% confidence
Finding
The module docstring labels the script as 'TikTok Shop ERP Logistics' and says it is for 'Fetch shop_cipher for logistics APIs'. However, the actual invoked operation is `get_authorized_shops`, which is not the warehouse-list logistics action described by the skill and instead aligns with authorization/shop selection behavior.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The script accepts an arbitrary `api` value from user-supplied JSON and forwards it to a generic logistics dispatcher, which can expose any registered Logistics endpoint rather than enforcing the manifest's stated warehouse-list-only scope. In an agent setting, this creates a scope-bypass path where callers may invoke broader logistics capabilities than intended, potentially reaching sensitive warehouse, return, or fulfillment-adjacent operations if they are registered downstream.

Intent-Code Divergence

Medium
Confidence
87% confidence
Finding
The module docstring explicitly describes the script as a generic registered Logistics API caller, which contradicts the declared skill scope of warehouse-list-only access. This mismatch is dangerous because it signals the implementation was designed for broader capability than users, reviewers, and policy controls may expect, increasing the likelihood of accidental overexposure and misuse.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
This script exposes a generic path/method proxy by accepting arbitrary JSON input and forwarding it to run_logistics_proxy, while the skill metadata claims a narrow purpose of only fetching warehouse lists. The usage text explicitly allows both logistics/ and authorization/ paths, creating a scope-expansion risk where callers may reach unintended API surfaces, including auth-related endpoints, through an apparently limited skill.

Static analysis

No suspicious patterns detected.