Back to skill

Security audit

出海匠 TikTok 店铺情报

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed paid TikTok Shop research integration, but it needs Review because sensitive credentials and login data can be sent to environment-configured hosts and local output paths are not safely constrained.

Install only if you trust LinkFox and the environment running the skill. Do not set LINKFOX_TOOL_GATEWAY, LINKFOX_LOGIN_API_URL, LINKFOX_AGENT_API_URL, or LINKFOX_AGENT_USER_API_URL to non-LinkFox hosts; avoid giving phone numbers or SMS codes through the agent unless you intentionally want account setup; confirm any paid plan/order before scanning a QR code; and expect full API responses plus caches to be saved locally under the workspace linkfox directory.

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/chuhaijiang_seller_search.py:37
Finding

Credentials and personal authentication data can be forwarded to unrestricted configurable origins

Content
View full analysis
str: """Gateway base URL: LINKFOX_TOOL_GATEWAY takes priority.""" return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") def get_api_url(): return get_api_base() + API_PATH def call_api(params): global _LAST_CALL_WAS_HTTP_ERROR _LAST_CALL_WAS_HTTP_ERROR = False api_url = get_api_url() api_key = get_api_key() data = json.dumps(params).encode("utf-8") headers = { "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/2.0", "SESSION_ID": (os.environ.get("SESSION_ID") or "").strip(), "MESSAGE_ID": os.environ.get("MESSAGE_ID", ""), "MODE_ID": os.environ.get("MODE_ID", ""), "APP_NAME": os.environ.get("APP_NAME", ""), } req = Request( api_url, data=data, headers=headers, method="POST", ) try: with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` Relevant onboarding origin configuration and credential-header construction: ```python def _agent_base() -> str: return _env_base( "LINKFOX_AGENT_API_URL", ...[truncated 5244 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/chuhaijiang_seller_search.py:247
Finding

Unsanitized SESSION_ID permits filesystem path traversal and writes outside the intended session directory

Content
View full analysis
str: """Prefer env SESSION_ID; otherwise generate a stable process-local ID.""" env = (os.environ.get("SESSION_ID") or "").strip() if env: return env if "_auto" not in _SESSION_CACHE: _SESSION_CACHE["_auto"] = ( time.strftime("%H%M%S", time.localtime(ts)) + "-" + secrets.token_hex(3) ) return _SESSION_CACHE["_auto"] def _ensure_session(ts: float) -> tuple[str, str]: """Return (linkfox_root, session_dir); session_dir always exists.""" date_str = time.strftime("%Y-%m-%d", time.localtime(ts)) sid = _session_id(ts) root = _linkfox_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _ensure_meta(root, session_dir, date_str, sid, ts) return root, session_dir ``` The resulting directory is subsequently used for metadata and API-response files: ```python def resolve_data_path(slug: str, ts: float, ext: str = "json") -> str: _, session_dir = _ensure_session(ts) sub = os.path.join(session_dir, "data") os.makedirs(sub, exist_ok=True) out = os.path.join(sub, f"{slug}-{int(ts * 1_000_000)}.{ext}") _update_meta( session_dir, skill=slug, kind="data", file_rel=os.path.relpat ...[truncated 3047 chars]
Remediation
View remediation
str: value = value.strip() if not _SESSION_ID_RE.fullmatch(value): raise ValueError("Invalid SESSION_ID") return value ``` 2. Explicitly reject absolute paths, path separators, `.` and `..`, even if a regular expression is also used. 3. Enforce containment after constructing the path: ```python base = os.path.realpath(os.path.join(root, date_str)) candidate = os.path.realpath(os.path.join(base, sid)) if os.path.commonpath([base, candidate]) != base: raise ValueError("SESSION_ID escapes the session root") ``` 4. Apply the same centralized validation function to all seven business scripts and `scripts/onboarding.py`. 5. Avoid silently normalizing malicious identifiers. Reject them and generate a new random session identifier only when `SESSION_ID` is absent, not when it is present but invalid. 6. Create files using restrictive permissions where practical. API response data and payment artifacts should not be world-readable. 7. Add cross-platform tests covering: - `../` and `..\` traversal - Absolute POSIX paths - Windows drive and UNC paths - Empty, overlong, and special-character identifiers - Symbolic-link and containment edge cases ]]>
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (42)

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The request target is derived from an environment-controlled base URL via LINKFOX_TOOL_GATEWAY and then sent with the Authorization API key and session headers. If an attacker can influence the environment, they can redirect the request to an attacker-controlled host and exfiltrate credentials and request data, which is especially risky because this script blindly trusts the override and performs no allowlisting.

Content

Scanner excerpt · scripts/chuhaijiang_seller_detail.py (reported line 80)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:
        _LAST_CALL_WAS_HTTP_ERROR = True

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

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The request URL is derived from LINKFOX_TOOL_GATEWAY, an environment variable, and the request also includes sensitive headers such as the API key plus session/app metadata. If an attacker can influence the runtime environment, they can redirect the POST to an attacker-controlled host and exfiltrate credentials and identifiers. In a skill that should only query a fixed vendor API, allowing endpoint override materially increases SSRF and secret-leak risk.

Content

Scanner excerpt · scripts/chuhaijiang_seller_rank_most_promoted.py (reported line 80)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:
        _LAST_CALL_WAS_HTTP_ERROR = True

Tainted flow: 'req' from os.environ.get (line 73, 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/chuhaijiang_seller_rank_top_selling.py (reported line 80)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:
        _LAST_CALL_WAS_HTTP_ERROR = True

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The request sends multiple environment-derived values, including the API key and metadata headers, to a network endpoint whose base URL is also controlled by the LINKFOX_TOOL_GATEWAY environment variable. If an attacker can influence the environment, they can redirect requests to an arbitrary host and exfiltrate credentials and session identifiers; in this skill context, that is especially risky because the skill is expected to query public research data, not transmit sensitive local execution metadata to arbitrary destinations.

Content

Scanner excerpt · scripts/chuhaijiang_seller_related_creators.py (reported line 80)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:
        _LAST_CALL_WAS_HTTP_ERROR = True

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The script builds its destination URL from the environment variable LINKFOX_TOOL_GATEWAY and then sends the API key, session identifiers, and request data to that endpoint via urlopen. Because this network sink is controllable through environment input and there is no allowlist or validation, a poisoned runtime environment can redirect sensitive data to an attacker-controlled server, causing credential and metadata exfiltration.

Content

Scanner excerpt · scripts/chuhaijiang_seller_related_products.py (reported line 80)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:
        _LAST_CALL_WAS_HTTP_ERROR = True

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The request target and multiple headers are derived from environment variables, including LINKFOX_TOOL_GATEWAY and session/app identifiers, and are sent directly via urlopen. Because the gateway base URL is overrideable, a compromised or untrusted runtime can redirect requests and exfiltrate the API key, user query parameters, and session metadata to an attacker-controlled endpoint.

Content

Scanner excerpt · scripts/chuhaijiang_seller_related_videos.py (reported line 80)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:
        _LAST_CALL_WAS_HTTP_ERROR = True

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

Critical
Category
Data Flow
Confidence
97% confidence
Finding

The request URL is derived from LINKFOX_TOOL_GATEWAY, an environment variable, and the code sends the Authorization API key plus session headers to whatever host that variable points to. In an agent/runtime environment where skills may inherit attacker-influenced environment variables, this enables credential exfiltration and arbitrary outbound POSTs to untrusted infrastructure.

Content

Scanner excerpt · scripts/chuhaijiang_seller_search.py (reported line 80)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:
        _LAST_CALL_WAS_HTTP_ERROR = True

Tainted flow: 'url' from os.environ.get (line 234, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
93% confidence
Finding

The code builds request destinations from environment-controlled base URLs and then sends sensitive data such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys to those endpoints. If an attacker can influence environment variables in the skill runtime, they can redirect authentication traffic to attacker-controlled infrastructure and exfiltrate credentials or tokens.

Content

Scanner excerpt · scripts/onboarding.py (reported line 195)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

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

Critical
Category
Data Flow
Confidence
93% confidence
Finding

The gateway request target is also derived from environment variables and used in urlopen with authentication headers, including the agent API key and request metadata. A malicious runtime configuration could redirect these authenticated requests to an attacker endpoint, leaking secrets and enabling unauthorized actions such as order creation or account queries.

Content

Scanner excerpt · scripts/onboarding.py (reported line 247)May include surrounding context.

python
headers["Content-Type"] = "application/json"
    req = Request(url, method=method, data=body_bytes, headers=headers)
    try:
        with urlopen(req, timeout=30) as resp:
            return json.loads(resp.read().decode())
    except urllib.error.HTTPError as e:
        status = e.code

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is presented as a public TikTok Shop market-intelligence tool, but the referenced behavior includes account login, API key issuance, account/team queries, package purchase, order creation, payment QR generation, and payment-status checks. That mismatch is security-significant because users may authorize a benign-seeming research skill without realizing it can interact with billing, identity, and account systems outside the stated purpose.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

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

python scripts/chuhaijiang_seller_rank_top_selling.py '{"country":"us","date":"20260824","granularity":"daily","pageSize":10}'

text

## Display Rules

1. State the marketplace, filters, current page, total count, and ranking date/granularity used.
2. For store lists, show store name, rating, product count, recent or interval sales/GMV, creator reach, region, and store ID when available.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The onboarding document directs the agent to handle authentication failures by walking users through account registration, SMS login, API key acquisition, and billing/purchase flows that are unrelated to the skill's declared read-only TikTok Shop research purpose. This expands the skill into credential handling and monetization workflows, increasing phishing, privacy, and unauthorized account/payment interaction risk if the instructions are followed automatically or presented as trusted guidance.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file explicitly authorizes SMS-based registration/login and paid plan ordering via scripts/onboarding.py, which is unjustified for a TikTok Shop analytics skill and teaches the agent to participate in identity verification and commerce flows. That creates a dangerous precedent for collecting sensitive inputs such as phone numbers and one-time codes, and for steering users into transactions outside the expected skill function.

Content

No source excerpt is available for this finding.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · references/onboarding.md (reported line 14)May include surrounding context.

md
示 JSON 里的 phone/agreements
   - 收到验证码后:`python scripts/onboarding.py login <phone> <code>`
   - 拿到 `api_key` 后把下面三平台配置转发给用户,提示重启会话生效:
     - Windows PowerShell(永久):`setx LINKFOX_AGENT_API_KEY "<key>"`
     - macOS zsh:`echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.zshrc && source ~/.zshrc`
     - Linux bash:`echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.bashrc && source ~/.bashrc`
     - 变量名 `LINKFOX_AGENT_API_KEY`(主推)或 `LINKFOXAGENT_API_KEY`(老规范)任一即可

**billing 场景**:`errcode=402` 或消息含 `算力/余额/quota/insufficient/充值/套餐到期`。
- `python scripts/onboarding.py list-plans` → 有 AskUserQuestion 就弹菜单,否则输出编号清单让用户选
- 校验 `plan_id` ∈ 清单、支付方式 ∈ 该套餐 `available_methods`(通常 `wechat/alipay`)
- `python scripts/onboarding.py order <plan_id> <method>` → 展示优先级 PNG

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This file implements account onboarding, SMS login, API key acquisition, subscription discovery, order creation, and payment QR generation, which are unrelated to the declared TikTok Shop public-store research purpose. Such scope expansion is dangerous because it introduces credential handling and monetization capabilities that can be abused and are not necessary for the advertised function.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The order and payment functions create purchasable orders and generate payment QR codes despite the skill being described as a market-research integration. In context, hidden or unjustified billing capability increases the risk of unauthorized charges, social engineering, or misuse of the agent environment for purchases unrelated to user intent.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill performs SMS login and API token generation for LinkFox accounts, which is not justified by the stated Chuhaijiang store-research role. This greatly expands the trust boundary by collecting authentication factors and minting reusable API credentials, creating a high-value target for abuse or interception.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill describes capabilities that involve environment variables, local file writes, and network access, but it does not declare any explicit tool scope or allowed-tools restrictions. In an agent setting, missing least-privilege boundaries increases the chance that the skill can access broader capabilities than users expect, especially since it also includes credential handling and persistent storage behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill states that complete API responses are always written to a JSON file under the working directory, but it does not prominently warn users that fetched data will be persisted locally. Even if the source is 'public market intelligence,' responses may still contain session-linked context, expiring signed URLs, or other operational metadata that users did not expect to retain on disk.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill instructs saving full API responses in a session-linked path inside the project directory for every call. Persisting complete responses by default broadens data exposure, increases retention of unnecessary fields, and can leak marketplace data or signed links to other users, tools, or future tasks that can access the same workspace.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file presents all operational instructions, warnings, and API usage details only in Chinese. Under the language/locale policy rule, forcing a single language without user opt-in or a documented justification can exclude users and constitutes a natural-language policy violation.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/api.md (reported line 273)May include surrounding context.

入口脚本会把 HTTP 错误或业务错误保存并回显,不会缓存失败结果。参数错误不会自动改条件重试。

curl 示例

bash
curl -X POST "${LINKFOX_TOOL_GATEWAY}/chuhaijiang/sellers/search" \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The instructions tell the user to provide a phone number and later a verification code for script-based registration without any privacy notice, consent language, or guidance on safe handling of personal data. In the context of an agent skill, this can normalize sensitive-data collection for a feature that does not need it, exposing users to privacy misuse or social-engineering risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file-level docstring presents usage and output behavior entirely in Chinese, and the script's summary/help messaging is oriented around that fixed locale. Under the policy, forcing a specific language without user choice is a natural-language policy violation unless the locale constraint is clearly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The script always writes the full API response to persistent storage under the working directory, regardless of whether the data is needed after the call. This creates unnecessary local retention of potentially sensitive business data and increases the risk of cross-task data exposure in shared workspaces or later unintended reuse.

Content

No source excerpt is available for this finding.