Back to skill

Security audit

TikTok 商品市场情报

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly a disclosed LinkFox market-research integration, but it bundles credential onboarding and billing actions with risky endpoint and API-key handling that users should review carefully.

Install only if you trust LinkFox with the product queries, uploaded images, API key, and billing/account flows. Avoid setting gateway or login endpoint override variables unless you control the destination, do not paste API keys into shared logs or shell history, and use the onboarding or payment commands only when you intentionally want account setup or a purchase order.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/chuhaijiang_product_detail.py:29
Finding
Credential Exfiltration Through Unvalidated Configurable API Endpoints<![CDATA[ ## Vulnerability Details **File Location**: `scripts/chuhaijiang_product_detail.py:29-31, 156-174`; equivalent behavior exists in all `scripts/chuhaijiang_product_*.py` clients and `scripts/upload_image.py`. Related configurable authentication endpoints exist in `scripts/onboarding.py:77-85, 229-247`. **Vulnerability Type**: Credential disclosure through untrusted endpoint configuration **Risk Level**: High ### Vulnerable Code ```python def get_api_base() -> str: return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") ``` ```python 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: raw = response.read().decode("utf-8") ``` Onboarding also permits independent overrides: ```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.linkfox.com") def _agent_user_base() -> str: return _env_base( "LINKFOX_AGENT_USER_API_URL", "https://agent-api.linkfox.com", ) ``` ### Technical Analysis The API destination is obtained directly from environment variables without validating its scheme or host ...[truncated 1834 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use fixed production origins for credential-bearing requests. 2. If endpoint overrides are required for development, enforce an explicit allowlist of trusted hostnames. 3. Require HTTPS and reject HTTP, user-information components, unusual ports, loopback addresses, link-local addresses, and private-network destinations. 4. Resolve and validate DNS results before connecting, with safeguards against DNS rebinding. 5. Disable redirects for requests containing credentials, or permit redirects only when the scheme and validated hostname remain unchanged. 6. Maintain separate development credentials for test endpoints. 7. Add automated tests confirming that credentials cannot be sent to non-allowlisted destinations. 8. Centralize endpoint and credential handling instead of duplicating the vulnerable client implementation across scripts. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/chuhaijiang_product_detail.py:156
Finding
Unnecessary Transmission of Agent Session and Message Metadata<![CDATA[ ## Vulnerability Details **File Location**: `scripts/chuhaijiang_product_detail.py:156-174`; the same headers are transmitted by all product clients and `scripts/upload_image.py`. **Vulnerability Type**: Excessive collection and disclosure of execution metadata **Risk Level**: Medium ### Vulnerable Code ```python 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: raw = response.read().decode("utf-8") ``` ### Technical Analysis The declared product-research operations require an API credential and product-query parameters. The implementation additionally forwards the agent's session ID, message ID, mode ID, and application name on every network request. The reviewed documentation does not establish that all of these identifiers are required for authentication or fulfillment of public market-data queries. Consequently, the implementation exceeds the minimum information needed for its declared functionality. These stable or semi-stable identifiers can allow the remote service to correlate requests with conversations, applications, and execution modes. ### Attack Path 1. The host agent exposes `SESSION_ID`, `MESSAGE_ID`, `MODE_ID`, or `APP_NAME` through environment variables. 2. The user invokes any product search, detail, ranking, relationship, review, image-sear ...[truncated 602 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `MESSAGE_ID`, `MODE_ID`, and `APP_NAME` unless a documented server-side requirement exists. 2. Avoid sending `SESSION_ID` for ordinary product queries. If request correlation is required, generate a short-lived random request identifier that cannot be linked to the agent session. 3. Obtain explicit user consent before transmitting identifiers used for analytics or cross-request tracking. 4. Document the purpose, retention period, and recipient of each transmitted metadata field. 5. Apply data-minimization rules in a shared HTTP client so future endpoints cannot silently add unrelated environment data. 6. Add tests that inspect outbound headers and fail when nonessential runtime metadata is present. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:476
Finding
API Key Exposure Through Standard Output and Plaintext Shell Configuration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/onboarding.py:476-489, 501-515`; related persistence instructions appear in `references/onboarding.md:9-15`. **Vulnerability Type**: Plaintext credential disclosure and insecure storage guidance **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), } ``` ```python def _emit(obj: dict) -> None: print(json.dumps(obj, ensure_ascii=False, indent=2)) ``` ```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 (source: {r['source']})", file=sys.stderr, ) return 0 return 1 ``` The onboarding documentation recommends shell commands equivalent to: ```bash echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY="<key>"' >> ~/.bashrc setx LINKFOX_AGENT_API_KEY "<key>" ``` ### Technical Analysis A successful login result contains the complete API key and is serialized directly to standard output. Agent runtimes, terminal sessions, CI systems, and orchestration platforms commonly capture standard output in transcripts or logs. The documented setup method additionally places the key directly in command text and persistent shell startup files. This can expose the key through shell history, process inspection, backup systems, support bundles, home-directory access, and accidental sharing of configuration files. ### Attack Path 1. A user runs the onboarding login command with a valid phone number and SMS code. 2. The script obtains or generates an API key. 3. `_emit()` prints the complete key to standa ...[truncated 759 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not return or print the complete API key through standard output. 2. Store the key directly in an operating-system credential manager, such as Windows Credential Manager, macOS Keychain, or a Linux secret service. 3. If file storage is unavoidable, create a dedicated credential file with owner-only permissions and avoid shell startup files. 4. Display only a short non-reversible fingerprint confirming which key was stored. 5. Use interactive secret input and commands that do not place credentials in shell history. 6. Warn users that agent transcripts and CI logs must never contain credentials. 7. Provide key revocation and rotation instructions. 8. Redact token-like fields from all exceptions, debug output, and structured command results. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/upload_image.py:65
Finding
Unvalidated Presigned Upload URL Can Redirect Image Bytes to an Unintended Host<![CDATA[ ## Vulnerability Details **File Location**: `scripts/upload_image.py:65-93` **Vulnerability Type**: Untrusted outbound upload destination **Risk Level**: Medium ### Vulnerable Code ```python data = result.get("data") if isinstance(result.get("data"), dict) else {} upload_url = data.get("url") os_key = data.get("os_key") or data.get("osKey") os_bucket = data.get("os_bucket") or data.get("osBucket") if not upload_url or not os_key: print( "Upload target response did not contain url and os_key.", file=sys.stderr, ) raise SystemExit(1) return ( str(upload_url), str(os_key), os_bucket, result.get("request_id"), result.get("errcode"), result.get("errmsg"), sorted(data.keys()), ) ``` ```python def upload_file(upload_url: str, file_path: Path, content_type: str) -> int: request = Request( upload_url, data=file_path.read_bytes(), headers={"Content-Type": content_type}, method="PUT", ) try: with urlopen(request, timeout=150) as response: if response.status not in (200, 201, 204): raise RuntimeError( f"unexpected upload status {response.status}" ) return response.status ``` ### Technical Analysis Uploading the user-selected image is necessary for the declared image-search functionality. However, the upload destination is accepted directly from the presign response without validating the URL scheme, destination hostname, resolved address, port, or redirect target. If the gateway or its response path is compromised, it can supply an arbitrary URL. The helper will read the complete selected file into memory and send it to that destination. A malicious URL could identify an attacker-controlled host or a local/private-network service. The PUT request does not include the LinkFox API key, which limits credential exposure, but the image bytes themselves may be sensitive. ### Attack ...[truncated 1031 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require the upload URL to use HTTPS. 2. Allow only documented object-storage hostname suffixes and expected ports. 3. Reject URLs containing user-information components or malformed hostnames. 4. Resolve the hostname and reject loopback, link-local, multicast, reserved, and private-network addresses. 5. Disable redirects for the PUT operation, or revalidate every redirect destination before following it. 6. Validate that the returned object key and bucket follow expected formats. 7. Consider streaming the upload rather than reading the complete file into memory. 8. Warn users that selected image contents are transmitted to external object storage. ]]>

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:162
Finding
Unpinned Runtime Dependency Installation Guidance<![CDATA[ ## Vulnerability Details **File Location**: `scripts/onboarding.py:162-186` **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Low ### Vulnerable Commands When optional packages are absent, the script instructs users to run commands equivalent to: ```bash pip install qrcode pillow pip install requests ``` ### Technical Analysis The installation instructions do not pin versions, provide package hashes, specify a trusted package index, or require an isolated environment. Package resolution therefore depends on the user's current Python package-index configuration and whatever versions are available at installation time. This is not evidence that the named packages are malicious. The risk arises from an uncontrolled supply-chain process: a compromised index, dependency substitution, malicious future release, or unsafe local package source could cause arbitrary installation-time code to execute. ### Attack Path 1. The onboarding command detects that `requests`, `qrcode`, or Pillow is unavailable. 2. The user follows the displayed installation command. 3. `pip` resolves packages and transitive dependencies from the user's configured index without a lockfile or hash verification. 4. A compromised or substituted package executes code during installation or later import. 5. That code runs with the privileges of the user performing the installation or invoking onboarding. ### Impact Assessment A malicious dependency could execute arbitrary code with the installing user's privileges. This could expose local files, environment variables, LinkFox credentials, browser data, or other secrets available to the Python process. The likelihood is reduced because the referenced package names are established projects, but the absence of version and integrity controls leaves the installation non-reproducible and unnecessarily dependent on current registry state. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Supply a reviewed dependency manifest with exact versions. 2. Include cryptographic hashes and install with hash verification enabled. 3. Use a trusted, explicitly configured package index. 4. Install dependencies in a dedicated virtual environment rather than the global interpreter. 5. Lock transitive dependencies as well as direct dependencies. 6. Add automated dependency scanning and update review. 7. Prefer packaging the Skill with its reviewed dependencies rather than directing users to install packages interactively at runtime. ]]>
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 (43)

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

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)
Confidence
96% confidence
Finding
The script copies multiple environment variables, including SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME, directly into outbound HTTP headers without validation or sanitization. If an attacker can influence these environment variables, they can inject unexpected header values or exfiltrate sensitive workflow context to the remote gateway; because the destination base URL is also overrideable via LINKFOX_TOOL_GATEWAY, the skill context makes this more dangerous by enabling those headers to be sent to an attacker-controlled endpoint.

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

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)
Confidence
94% confidence
Finding
The script builds outbound HTTP headers from untrusted environment variables, including SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME, and then sends them to a URL whose base can also be overridden by the LINKFOX_TOOL_GATEWAY environment variable. This creates a real exfiltration channel: an attacker controlling the execution environment can redirect traffic to an attacker-owned endpoint and force transmission of request parameters, API key authorization, and session metadata.

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

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)
Confidence
96% confidence
Finding
The request sent via urlopen includes multiple headers populated directly from environment variables, and the destination host is also overrideable through LINKFOX_TOOL_GATEWAY. In this combination, an attacker who can influence the execution environment can exfiltrate session identifiers, message metadata, and the API key-bearing request to an arbitrary server, which is a real SSRF/data-exfiltration risk rather than a harmless configuration pattern.

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

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)
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 167, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)
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 167, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)
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 167, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)
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 167, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)
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 167, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)
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 167, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)
Confidence
95% confidence
Finding
The script builds the request URL from the environment variable LINKFOX_TOOL_GATEWAY and forwards multiple environment-derived headers, including the API key in Authorization, to whatever host that variable points to. If an attacker can influence the execution environment, they can redirect requests to an attacker-controlled server and exfiltrate credentials and request data; in an agent/tooling context this is especially risky because environment variables are often inherited from orchestration layers.

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
95% confidence
Finding
The POST destination is derived from environment-controlled base URLs, and this request carries sensitive data such as SMS login payloads, access tokens, refresh tokens, and generated API tokens. If an attacker can influence environment variables, the script can be redirected to an attacker-controlled endpoint, causing credential exfiltration and account compromise. The skill context makes this more dangerous because the file is already handling onboarding, authentication, and token issuance unrelated to the declared TikTok research purpose.

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
95% confidence
Finding
The gateway request URL is built from environment-controlled base configuration and includes Authorization and other session headers. An attacker who can alter the environment can redirect these authenticated requests to an external server and capture API keys, session identifiers, and billing-related traffic. This is especially concerning because the same script can create orders and query account information, expanding the blast radius beyond simple data access.

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

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        with urlopen(request, timeout=150) as response:
            result = json.loads(response.read().decode("utf-8"))
    except HTTPError as exc:
        print(f"Failed to request upload target: HTTP {exc.code}: {exc.reason}", file=sys.stderr)
Confidence
92% confidence
Finding
The request to the gateway includes multiple HTTP headers sourced directly from environment variables, and the destination base URL is also overridable via LINKFOX_TOOL_GATEWAY. In an untrusted or attacker-influenced runtime, this can exfiltrate sensitive session metadata and the API key to an attacker-controlled endpoint or enable SSRF-like outbound requests, which is especially risky because this script is designed to run with privileged automation credentials.

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

Critical
Category
Data Flow
Content
method="PUT",
    )
    try:
        with urlopen(request, timeout=150) as response:
            if response.status not in (200, 201, 204):
                raise RuntimeError(f"unexpected upload status {response.status}")
            return response.status
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
95% confidence
Finding
The skill claims to be a product-intelligence tool but also performs local file reads and uploads via presigned URLs, which materially changes the security posture. File access plus network upload can enable exfiltration of local data or unintended transmission of sensitive user content, especially when the upload behavior is not prominently declared as a separate privileged action.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill claims to be a product-intelligence tool but also performs local file reads and uploads via presigned URLs, which materially changes the security posture. File access plus network upload can enable exfiltration of local data or unintended transmission of sensitive user content, especially when the upload behavior is not prominently declared as a separate privileged action.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill claims to be a product-intelligence tool but also performs local file reads and uploads via presigned URLs, which materially changes the security posture. File access plus network upload can enable exfiltration of local data or unintended transmission of sensitive user content, especially when the upload behavior is not prominently declared as a separate privileged action.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
python scripts/chuhaijiang_product_reviews.py '{"country":"us","id":"1732052189676081387","pageSize":10}'
```

## Display Rules

1. State the marketplace, total count, current page, filters, and ranking window used.
2. For product lists, show image, title, price range, sales/GMV window, rating, store, and product ID when available.
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
This file implements account onboarding, SMS login, API key retrieval, plan listing, purchasing, and payment QR generation, which are materially unrelated to a TikTok product research skill. Such hidden scope expansion increases the chance of credential harvesting, unwanted billing actions, and abuse of user trust, especially when bundled into a skill that users expect to only query public market data.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The script can create purchase orders and produce payment QR codes, introducing a billing workflow that has no clear relation to public TikTok product research. This expands the attack surface from data access to financial operations, increasing the risk of unauthorized charges, social engineering, and misuse if invoked unexpectedly within the skill environment.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The code obtains or generates LinkFox API tokens after authenticating by phone, which grants durable access beyond the immediate user session. For a skill whose stated purpose is public TikTok product research, provisioning credentials is unnecessary and creates a high-risk path for privilege expansion and unauthorized downstream API use.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill declares no explicit tool/permission scope even though its content clearly describes access to environment variables, local file read/write, and network operations, including external HTTP PUT uploads. This increases the blast radius of prompt or implementation mistakes because consumers and enforcement layers cannot easily constrain what the skill is allowed to do.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
This markdown file is natural-language documentation, and it appears to require Chinese comprehension throughout while providing no alternative language option or opt-in. That can violate language/locale policy when a skill forces a specific language without user choice or a clearly documented regional justification.

External Transmission

Medium
Category
Data Exfiltration
Content
| 501 | 参数校验失败 | 根据 `errmsg` 修正参数;真实非法国家码会返回此码 |
| 其他非 200 | 业务异常 | 回显 `errmsg`,不得自动连续重试付费接口 |

## curl 示例

### 商品搜索
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.