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

Content
View full analysis
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
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/chuhaijiang_product_detail.py:156
Finding

Unnecessary Transmission of Agent Session and Message Metadata

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:476
Finding

API Key Exposure Through Standard Output and Plaintext Shell Configuration

Content
View full analysis
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=""' >> ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc setx LINKFOX_AGENT_API_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
View remediation

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

Content
View full analysis
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
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:162
Finding

Unpinned Runtime Dependency Installation Guidance

Content
View full analysis
Remediation
View remediation
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
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.

Content

Scanner excerpt · scripts/chuhaijiang_product_detail.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
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.

Content

Scanner excerpt · scripts/chuhaijiang_product_rank_top_selling.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
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.

Content

Scanner excerpt · scripts/chuhaijiang_product_related_creators.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

Tainted flow: 'req' from os.environ.get (line 167, 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_product_image_search.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

Tainted flow: 'req' from os.environ.get (line 167, 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_product_rank_most_promoted.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

Tainted flow: 'req' from os.environ.get (line 167, 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_product_rank_new_arrivals.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

Tainted flow: 'req' from os.environ.get (line 167, 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_product_related_lives.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

Tainted flow: 'req' from os.environ.get (line 167, 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_product_related_videos.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

Tainted flow: 'req' from os.environ.get (line 167, 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_product_reviews.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
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.

Content

Scanner excerpt · scripts/chuhaijiang_product_search.py (reported line 174)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            raw = response.read().decode("utf-8")
            try:
                return json.loads(raw)

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

Critical
Category
Data Flow
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.

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
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.

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

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

Critical
Category
Data Flow
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.

Content

Scanner excerpt · scripts/upload_image.py (reported line 49)May include surrounding context.

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

Tainted flow: 'request' from os.environ.get (line 34, 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/upload_image.py (reported line 91)May include surrounding context.

python
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

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

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 112)May include surrounding context.

python scripts/chuhaijiang_product_reviews.py '{"country":"us","id":"1732052189676081387","pageSize":10}'

text

## 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.

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
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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

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 322)May include surrounding context.

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

## curl 示例

### 商品搜索