Back to skill

Security audit

TikTok官方-店铺数据分析

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly supports TikTok Shop video analytics, but it also exposes broader proxy and authorization access that users should review before installing.

Install only if you trust the publisher and runtime environment. Review or restrict the gateway environment variables, avoid exposing production API keys to untrusted shells, and prefer using the named get_video_performances script over the generic proxy unless the broader authorization and analytics access is intentional.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_shop_analytics_common.py:15
Finding

Configurable Gateway Allows Sensitive Credentials to Be Sent to an Untrusted Destination

Content
View full analysis
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 network request is necessary for the Skill's declared functionality, but its destination is not restricted to the documented LinkFox gateway. The `LINKFOX_TOOL_GATEWAY` and `TIKTOK_SHOP_API_BASE_URL` environment variables can replace the entire gateway origin with an arbitrary URL. The code does not enforce HTTPS, validate the destination hostname, restrict ports, reject URL user information, or otherwise verify that the destination belongs to LinkFox. Every request to the configured endpoint includes: - The LinkFox agent API key in the `Authorization` header. - The merchant's `openId` in ...[truncated 1701 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/_analytics_api_runner.py:244
Finding

Generic ERP Proxy Exposes Broader API Access Than the Declared Analytics Operations

Content
View full analysis
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("analytics/") 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"), ) out = { "developerProxy": proxy, "resolvedPath": str(path).lstrip("/"), "appType": "erp", } if shop_cipher: out["shop_cipher"] = shop_cipher if query_string: ...[truncated 4076 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (20)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/_shop_analytics_common.py (reported line 84)May include surrounding context.

python
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 ""

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented available scripts include retrieval of authorized shops, which is operationally different from fetching video performance analytics and overlaps with authorization/shop-selection workflows the description says are excluded. This is dangerous because it leaks or expands access to account/shop metadata and undermines trust in the skill's declared boundaries.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented available scripts include retrieval of authorized shops, which is operationally different from fetching video performance analytics and overlaps with authorization/shop-selection workflows the description says are excluded. This is dangerous because it leaks or expands access to account/shop metadata and undermines trust in the skill's declared boundaries.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The documented available scripts include retrieval of authorized shops, which is operationally different from fetching video performance analytics and overlaps with authorization/shop-selection workflows the description says are excluded. This is dangerous because it leaks or expands access to account/shop metadata and undermines trust in the skill's declared boundaries.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The documented available scripts include retrieval of authorized shops, which is operationally different from fetching video performance analytics and overlaps with authorization/shop-selection workflows the description says are excluded. This is dangerous because it leaks or expands access to account/shop metadata and undermines trust in the skill's declared boundaries.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented available scripts include retrieval of authorized shops, which is operationally different from fetching video performance analytics and overlaps with authorization/shop-selection workflows the description says are excluded. This is dangerous because it leaks or expands access to account/shop metadata and undermines trust in the skill's declared boundaries.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The generic run_analytics_proxy accepts caller-supplied path and method and forwards them to /tiktokShop/developerProxy with only a minimal prefix check for analytics/ before auto-resolving shop_cipher. That means a skill advertised as only supporting Get Video Performances can be used to reach arbitrary ERP proxy endpoints and HTTP methods, creating scope expansion and potential unauthorized access to broader TikTok Shop APIs beyond the manifest-declared capability.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This wrapper advertises and forwards a generic proxy request shape containing user-controlled path and method, and its own usage text explicitly allows both analytics/ and authorization/ prefixes. In an analytics-only skill that explicitly says it does not include authorization, exposing authorization routes expands the reachable backend surface and can enable unintended access to auth-related endpoints through the ERP developerProxy, creating a capability mismatch between the manifest and the actual code.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The inline help text tells callers that authorization/ is an allowed path prefix, directly contradicting the skill description that says the skill has no authorization scope. That contradiction is dangerous because it normalizes and encourages use of auth-related backend routes from an analytics wrapper, increasing the chance of misuse, privilege creep, or accidental exposure of sensitive authorization operations.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill advertises executable scripts and proxy-based API access but does not declare any explicit tool scope or permissions boundaries. In an agent environment, undeclared access to shell, network, and environment increases the chance of over-privileged execution and makes it harder to constrain what the skill can do if invoked unexpectedly or with attacker-controlled inputs.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The referenced API documentation is for listing authorized shops, while the skill is declared as a TikTok Shop video analytics capability. This mismatch can cause the agent to invoke or expose authorization-scoped shop metadata instead of the intended analytics endpoint, leading to overbroad data access, privacy leakage, or incorrect operational behavior. In this context, the skill depends on shop selection via openId, so mixing authorization and analytics references increases the chance of confusing privilege boundaries and retrieving sensitive shop identifiers such as cipher values unnecessarily.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file presents the operational instructions and safety notes only in Chinese, including the key usage guidance in the 'Agent 注意事项' section. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation unless the constraint is explicitly justified.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

To resolve shop_cipher, the code calls the authorization/202309/shops endpoint to enumerate authorized shops. The manifest explicitly says the skill does not include authorization, so embedding an authorization-domain API call extends capability beyond the stated analytics-only purpose, even if used as a convenience dependency.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code whitelist allows both analytics and authorization paths even though the skill metadata says the skill does not include authorization. In a skill-routing context, this creates a capability mismatch that could let this analytics skill invoke auth-related upstream endpoints through the shared developer proxy, expanding privileges beyond the declared purpose and potentially bypassing policy or review boundaries.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/_shop_analytics_common.py (reported line 41)May include surrounding context.

python
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,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The helper sends request data to a remote endpoint and includes SESSION_ID, MODE_ID, and APP_NAME from the environment in HTTP headers. While the code performs the network call, it provides no confirmation prompt, user-facing disclosure, or warning comment/docstring indicating that user or system metadata will be transmitted.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script invokes run_analytics_api("get_authorized_shops", ...) even though the skill metadata and declared purpose are limited to video performance analytics. This creates a scope mismatch that can expose shop-authorization inventory data to callers who expected only analytics access, increasing the risk of unintended data access and privilege expansion within the skill surface.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The substantive instructional content in this reference is written in Chinese, and the file does not indicate that language is optional or provide an alternative locale. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script emits a user-facing reason string in Chinese only: "linkfox-tiktok-shop-analytics 依赖 linkfox-tiktok-shop-auth,未找到其 SKILL.md。" This forces a specific language for at least part of the output without offering a language choice or documenting a justified locale constraint.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The docstring says 'TikTok Shop ERP analytics — get_authorized_shops', framing the file as an analytics operation. But the actual API call on L22 performs 'get_authorized_shops', which is about authorization/shop discovery rather than analytics data, creating a documentation-to-code intent mismatch.

Content

No source excerpt is available for this finding.