Back to skill

Security audit

出海匠 TikTok 视频情报

Security checks for vulnerabilities and agentic risk

Overview

The skill can perform the advertised TikTok research, but it also handles LinkFox login, API keys, billing, and payment-order flows with weak safeguards, so it needs Review before installation.

Install only if you trust LinkFox with your TikTok research queries, LinkFox account details, API key, and any billing actions. Verify service URL environment variables before use, avoid pasting SMS codes or API keys into shared logs, review any shell-profile key export, and clean the local linkfox output directory if saved responses should not remain on disk.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/chuhaijiang_video_search.py:38
Finding
Credentials and authentication data can be transmitted to unrestricted environment-controlled destinations<![CDATA[ ## Vulnerability Details **File Location**: `scripts/chuhaijiang_video_search.py:38-72`; equivalent behavior exists in `scripts/chuhaijiang_video_detail.py:38-72`, `scripts/chuhaijiang_video_related_products.py:38-72`, and `scripts/chuhaijiang_video_reviews.py:38-72`. Authentication endpoint overrides also exist in `scripts/onboarding.py:68-89`, with sensitive requests at `scripts/onboarding.py:208-221`, `scripts/onboarding.py:399-418`, and `scripts/onboarding.py:451-459`. **Vulnerability Type**: Unrestricted destination override for sensitive network requests **Risk Level**: High ### Vulnerable Code ```python def get_api_base() -> str: """Gateway base URL: LINKFOX_TOOL_GATEWAY takes precedence.""" 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 get_api_key(): key = os.environ.get("LINKFOX_AGENT_API_KEY") or os.environ.get( "LINKFOXAGENT_API_KEY" ) if not key: sys.exit(1) return key def call_api(params): 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") ``` The onboarding script similarly permits replacement of every sensitive service destination: ```python def _agent_base() -> str: return _env_base( "LINKFOX_AGENT_API_URL", "https://tool-gateway.linkfox.com", "LINKFOX_TOOL_GATEWAY", ) def _login_base() -> str: return _env_base("LINKFOX_LOGIN_API_URL", "https://api.lin ...[truncated 3211 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require `https` for every configured service URL and reject all other schemes. 2. Enforce an explicit hostname allowlist, such as the documented LinkFox production domains. 3. Reject URLs containing user information, unexpected ports, fragments, or malformed hostnames. 4. Disable automatic redirects or validate every redirect target before forwarding authorization headers. 5. Do not attach credentials until the final destination has passed validation. 6. Separate development endpoint overrides from production behavior and require an explicit, clearly named unsafe-development option. 7. Use separate credentials with narrowly scoped permissions for testing environments. 8. Minimize context headers: transmit `SESSION_ID`, `MESSAGE_ID`, `MODE_ID`, and `APP_NAME` only when required by the selected endpoint. 9. Add automated tests proving that non-HTTPS, off-domain, and redirect-based destinations are rejected. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:486
Finding
Onboarding exposes the complete API key through standard output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/onboarding.py:486-501` **Vulnerability Type**: Plaintext credential exposure through process output **Risk Level**: High ### Vulnerable Code ```python return { "api_key": tok["api_key"], "phone": masked, "group_id": info["group_id"], "member_id": info["member_id"], "source": tok["source"], "nick_name": lg.get("nick_name", ""), "team_name": info.get("team_name", ""), "is_new_user": lg.get("is_new_user", False), } def _emit(obj: dict) -> None: print(json.dumps(obj, ensure_ascii=False, indent=2)) ``` The login command sends the returned object directly to the output function: ```python def _cmd_login(args) -> int: r = login_and_get_key(args.phone.strip(), args.code.strip(), args.channel) _emit(r) if "api_key" in r: print(f"{TAG} API key obtained successfully", file=sys.stderr) return 0 return 1 ``` ### Technical Analysis The onboarding flow returns the complete generated or retrieved API key in a dictionary and serializes that dictionary to stdout. Standard output is not a secure secret-delivery channel. In Agent-driven, CI, terminal-multiplexer, or automated environments, stdout may be retained in conversation transcripts, build logs, command histories, process captures, or monitoring systems. The behavior also conflicts with the Skill documentation's stated rule that credentials should not be exposed. Masking the phone number does not mitigate exposure of the more sensitive API key. ### Attack Path 1. A user runs `scripts/onboarding.py login` with a valid phone number and SMS verification code. 2. The authentication flow obtains or generates an API key. 3. `_cmd_login()` passes the result to `_emit()`. 4. `_emit()` prints the complete key as JSON to stdout. 5. An Agent transcript, CI logger, shell capture, terminal log, or other observer retains the output. 6. A party with access to the retained output extracts and reuses the credentia ...[truncated 437 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not include the complete API key in normal JSON output. 2. Store the key directly in an operating-system credential manager or another approved secret store. 3. If file-based storage is necessary, create a dedicated configuration file with owner-only permissions and avoid writing the key to project artifacts. 4. Return only a short fingerprint, key identifier, or masked value to confirm successful setup. 5. If revealing a key is unavoidable, require an explicit interactive confirmation and write it directly to a terminal rather than a pipeable stdout stream. 6. Ensure error messages never include raw API responses that might contain credentials. 7. Update onboarding documentation so users are not instructed to copy secrets through Agent messages or other logged channels. 8. Add regression tests that fail if `api_key`, access tokens, refresh tokens, or verification codes appear in stdout or stderr. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/chuhaijiang_video_search.py:247
Finding
Unsanitized SESSION_ID permits output-path traversal<![CDATA[ ## Vulnerability Details **File Location**: `scripts/chuhaijiang_video_search.py:247-264`; equivalent behavior exists in `scripts/chuhaijiang_video_detail.py:247-264`, `scripts/chuhaijiang_video_related_products.py:247-264`, `scripts/chuhaijiang_video_reviews.py:247-264`, and `scripts/onboarding.py:153-158`. **Vulnerability Type**: Path traversal through an environment-derived directory component **Risk Level**: Medium ### Vulnerable Code ```python def _session_id(ts: float) -> str: """Prefer SESSION_ID; otherwise generate an identifier.""" 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]: 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 ``` Onboarding uses the same unvalidated value: ```python def session_dir() -> str: ts = time.time() sid = (os.environ.get("SESSION_ID") or "").strip() or ( time.strftime("%H%M%S", time.localtime(ts)) + "-" + secrets.token_hex(3)) path = os.path.join(_linkfox_root(), time.strftime("%Y-%m-%d", time.localtime(ts)), sid) os.makedirs(path, exist_ok=True) return path ``` ### Technical Analysis `SESSION_ID` is treated as a trusted directory name, but it is obtained directly from the environment. The value is not checked for: - `..` traversal components. - Absolute paths. - Platform-specific directory separators. - Drive prefixes on Windows. - Excessive length or special filesystem names. Because `os.path.join()` discards preceding components when a later comp ...[truncated 1573 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Restrict session identifiers to a conservative pattern such as `[A-Za-z0-9_-]{1,64}`. 2. Reject absolute paths, drive-qualified paths, `.` and `..` components, null bytes, and all directory separators. 3. Resolve the candidate path with `os.path.realpath()` before creating it. 4. Use `os.path.commonpath()` to verify that the resolved path remains inside the expected session root. 5. Reject the operation instead of silently normalizing an invalid externally supplied identifier. 6. Create files using restrictive permissions where supported. 7. Use atomic, exclusive file creation when overwriting an existing file is not required. 8. Apply the same validation helper consistently to all four business scripts and the onboarding script. 9. Add cross-platform tests for Unix absolute paths, Windows drive paths, UNC paths, traversal components, and mixed separators. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/onboarding.py:33
Finding
Onboarding recommends installation of unpinned third-party dependencies<![CDATA[ ## Vulnerability Details **File Location**: `scripts/onboarding.py:33-36`, `scripts/onboarding.py:160-166`, and `scripts/onboarding.py:183-188` **Vulnerability Type**: Unpinned runtime dependency installation guidance **Risk Level**: Medium ### Vulnerable Code ```python try: import requests except ImportError: requests = None ``` ```python def render_qr(content: str, out_dir: str) -> dict: try: import qrcode except ImportError: err = "Missing qrcode dependency; run: pip install qrcode pillow" print(f"{TAG} render_qr: {err}", file=sys.stderr) return {"png_path": None, "ascii_qr": None, "error": err} ``` ```python def _require_requests() -> None: if requests is None: raise RuntimeError( "Missing requests dependency; run: pip install requests" ) ``` No dependency lockfile, exact version constraints, or package hashes are present in the audited project structure. ### Technical Analysis The onboarding path depends on `requests`, `qrcode`, and Pillow, but directs users to install package names without versions or integrity hashes. Installation behavior consequently depends on the latest package versions and the package index configured in the user's environment. This is a supply-chain hardening weakness rather than evidence that the named packages are malicious. Risks include version drift, compromised future releases, malicious package-index substitution, or unexpected dependency resolution from an untrusted mirror. Because imported Python packages execute code in the user's process, compromise of a resolved dependency can affect all data handled by onboarding, including credentials and payment information. ### Attack Path 1. A user invokes onboarding in an environment where one or more dependencies are missing. 2. The script instructs the user to run an unpinned `pip install` command. 3. The user's package manager resolves packages from its configured index or mirror ...[truncated 727 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a reviewed dependency manifest with exact versions. 2. Supply cryptographic hashes and install with hash verification, such as `pip install --require-hashes`. 3. Commit a lockfile generated from the reviewed dependency set. 4. Document and enforce use of a trusted package index. 5. Install onboarding dependencies in an isolated virtual environment rather than the user's global Python environment. 6. Periodically scan and update pinned dependencies through a controlled review process. 7. Consider replacing `requests` with the standard-library HTTP implementation already used elsewhere in the project. 8. Make QR rendering optional without requiring package installation during a sensitive authentication or payment workflow. ]]>
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 (31)

Tainted flow: 'req' from os.environ.get (line 73, 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:
        _LAST_CALL_WAS_HTTP_ERROR = True
Confidence
97% confidence
Finding
The request destination is partly controlled by the LINKFOX_TOOL_GATEWAY environment variable, and the code blindly forwards sensitive headers including the API key plus SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME to whatever host that variable specifies. In an agent or multi-tenant runtime where environment variables can be influenced, this enables credential and metadata exfiltration to an attacker-controlled server via urlopen.

Tainted flow: 'req' from os.environ.get (line 73, 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:
        _LAST_CALL_WAS_HTTP_ERROR = True
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'req' from os.environ.get (line 73, 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:
        _LAST_CALL_WAS_HTTP_ERROR = True
Confidence
94% confidence
Finding
The request sent via urlopen includes multiple HTTP headers populated directly from environment variables, and the destination base URL is also overridable through LINKFOX_TOOL_GATEWAY. In an agent/runtime context, environment variables are often influenced by the host or orchestration layer, so this creates a true SSRF/exfiltration risk: secrets such as the API key and session metadata can be transmitted to an attacker-controlled endpoint if the gateway variable is poisoned.

Tainted flow: 'req' from os.environ.get (line 73, 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:
        _LAST_CALL_WAS_HTTP_ERROR = True
Confidence
97% confidence
Finding
The request destination and several outbound headers are influenced by environment variables, especially LINKFOX_TOOL_GATEWAY and SESSION_ID/MESSAGE_ID/MODE_ID/APP_NAME, and the code sends the Authorization API key to whatever base URL is configured. In a hostile or multi-tenant execution environment, an attacker who can control environment variables can redirect requests to an attacker-controlled server and exfiltrate the API key and request metadata, which is more serious here because this skill is specifically a networked data-access tool.

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

Critical
Category
Data Flow
Content
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 = ""
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
Data Flow
Content
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
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill is presented as a read-only TikTok research capability, but it also instructs the agent to handle onboarding, authentication, billing, order creation, payment QR generation, account/team lookup, and local file output. This hidden expansion into identity, payment, and account-management workflows materially changes the trust boundary and could lead to credential handling, unwanted charges, or sensitive account actions without clear user understanding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
These examples were production-validated with non-empty semantic results. IDs are volatile public-market examples; use a fresh search result when they stop resolving.

## Display Rules

1. State request context/site code, filters, sort, page, page size, and returned total.
2. For search results, show caption, video ID, creator, country, plays, likes, comments, shares, engagement rate, and product/commerce metrics only when returned.
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

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

High
Category
YARA Match
Content
示 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
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The file implements SMS login, API key issuance, package listing, and ordering flows that are unrelated to a TikTok public-video research skill. This expands the skill from data retrieval into account onboarding and monetization, creating unnecessary credential-handling and financial-operation attack surface in a context where users would not expect it.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
Order creation and QR payment rendering enable real billing actions inside a skill whose stated purpose is TikTok video analysis. In this context, financial operations are especially risky because they can trigger purchases, payment artifact generation, and session-linked billing behavior users do not associate with simple research queries.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The code collects phone numbers and SMS codes, performs login, and returns API keys, which is far beyond the declared scope of a TikTok research tool. In a mismatched skill context, credential capture and token minting are dangerous because they normalize sensitive-auth flows where users expect content analysis, increasing phishing and misuse risk.

Missing User Warnings

High
Confidence
98% confidence
Finding
This login flow transmits a phone number and SMS code to remote services and then returns an API key, all without strong in-file warnings or explicit consent controls. Because the skill is supposed to research TikTok videos, this behavior is contextually dangerous and resembles credential harvesting or covert account bootstrap.

Missing User Warnings

High
Confidence
97% confidence
Finding
The order command performs a real purchase path and then generates a payment QR code without a confirmation prompt. In a research-oriented skill, triggering billable transactions without a strong user-approval checkpoint creates a significant risk of accidental or manipulated purchases.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill declares no explicit tool scope even though its documented behavior includes environment access, file writes, and network/API calls. Without an allowlist or permissions boundary, an agent may invoke broader capabilities than users expect, increasing the chance of unintended data access, filesystem writes, or outbound requests.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This markdown file contains user-facing operational instructions exclusively in Chinese, including API usage, error handling, and safety guidance. Under the language/locale policy, forcing a specific language without user opt-in or clear justification is a natural-language policy violation.

External Transmission

Medium
Category
Data Exfiltration
Content
| 视频带货商品 | 18 |
| 视频评论 | 18 |

## curl 示例

```bash
curl --request POST "${LINKFOX_TOOL_GATEWAY}/chuhaijiang/videos/search" \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
89% confidence
Finding
The manifest describes this skill as researching public TikTok videos via Chuhaijiang, limited to search, detail, related products, and comment drilling. The file additionally documents a Feedback API endpoint and conditions for submitting reports to a separate service, which is a distinct outbound capability not mentioned in the manifest’s stated scope.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
A public feedback submission API is not an obvious requirement for searching TikTok videos, fetching video details, related products, or comments. Even though the documentation restricts it to user-authorized situations, it still represents an extra data-export capability outside the skill’s core research purpose as described in the manifest.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The onboarding instructions direct the agent to collect a user's phone number and use it in a script-driven registration/login flow, but provide no privacy notice, consent language, retention limits, or handling constraints for that personal data and OTP flow. In an agent setting, this increases the risk of unnecessary collection, insecure transmission, logging of sensitive identifiers, and mishandling of account-creation credentials.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script sends request parameters plus session/application metadata to a remote endpoint automatically, without any runtime notice or consent step in the execution path. In an agent setting, this can expose user task context or identifiers to an external service unexpectedly, especially because LINKFOX_TOOL_GATEWAY can redirect traffic to a different host via environment configuration.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script persistently stores full API responses in both cache files and session data files under the working directory, and the header comments even mandate this behavior. If responses contain sensitive business data, identifiers, or user-derived content, this creates a local confidentiality risk and expands the retention surface beyond the immediate execution.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The script always persists the full API response to the local project directory, including potentially sensitive review data, identifiers, or other user-linked metadata, without runtime opt-in or redaction. In an agent skill context this increases data exposure because responses remain on disk beyond the immediate task and may be accessible to other processes, users, or later workflow steps.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script always writes the full API response to a project-local file before deciding what to print, which can persist sensitive or regulated data such as TikTok video metadata, comments, or linked commerce information without an explicit runtime confirmation. In shared workspaces or repositories this increases the risk of unintended retention, later disclosure, or accidental commit of collected data.

Natural-Language Policy Violations

Medium
Confidence
99% confidence
Finding
The file's user-facing documentation and messages are entirely in Chinese, and the flow is explicitly tied to Chinese phone numbers and payment methods without offering any language or locale choice. This is a natural-language policy concern because the skill forces a specific language/locale experience rather than making it opt-in or clearly documenting a justified regional constraint.

Static analysis

No suspicious patterns detected.