Back to skill

Security audit

Temu以图搜同款

Security checks for vulnerabilities and agentic risk

Overview

The skill performs the stated Temu image search, but it also publicly uploads images, silently reports feedback externally, and handles credentials and payments with weak scoping.

Review this skill carefully before installing. Do not use it with private, personal, unreleased, or confidential images unless you accept public LinkFox OSS hosting. Avoid SMS-login onboarding through the agent when possible, avoid persisting API keys in shell startup files, and do not run it in an environment where LINKFOX_* endpoint variables or SESSION_ID may be attacker-controlled.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (6)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:131
Finding

Silent Disclosure of User Statements and Intent Through Automatic Feedback Reporting

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:68
Finding

Environment-Controlled API Endpoints Can Receive LinkFox Credentials and Authentication Data

Content
View full analysis
str: """Gateway base URL: environment value takes precedence.""" return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") ``` The search request sends the API key and session metadata to that base: ```python req = Request( get_api_url(), data=json.dumps(params).encode("utf-8"), headers={ "Authorization": get_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", ""), }, method="POST", ) ``` Onboarding independently permits all credential-bearing service bases to be replaced: ```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", ) ``` Access tokens are then attached to requests: ```python if access_token: h["authorization"] = access_token h["uid"] = ( _uid_header(access_token, user_id) if user_id else _LOGIN_FIXED_UID ) ``` The onboarding flow also sends tokens in request bodies: ```python resp = _http_post( f"{_agent_user_base()}/account/loginByToken", { "token": acce ...[truncated 2358 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/geekbi_temu_goods_image_search.py:35
Finding

Unsanitized SESSION_ID Permits Writes Outside the Intended Session Directory

Content
View full analysis
str: 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"] ``` ```python 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 ``` It later writes full API responses under that resolved path: ```python out_path = resolve_data_path(SLUG, time.time()) try: with open(out_path, "w", encoding="utf-8") as file: file.write(serialized) ``` Onboarding repeats the pattern for payment QR output: ```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 not constrained to a safe identifier. It may contain: - Absolute paths - `..` traversal components - Platform-specific path separators - Unexpectedly long or specially named components In Pytho ...[truncated 1579 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:475
Finding

Generated API Keys Are Printed in Full and Recommended for Plaintext Shell Persistence

Content
View full analysis
None: print(json.dumps(obj, ensure_ascii=False, indent=2)) 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} Successfully obtained API key " f"(source: {r['source']})", file=sys.stderr, ) return 0 return 1 ``` The onboarding instructions recommend embedding the key in shell commands and startup profiles: ```bash setx LINKFOX_AGENT_API_KEY "" echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc && source ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc && source ~/.bashrc ``` ### Technical Analysis Standard output may be captured by the Agent, terminal scrollback, shell command substitution, CI logs, orchestration logs, or session recording. Printing a complete long-lived API key therefore unnecessarily broadens its exposure. The recommended persistence commands additionally place the secret: - In shell command history - In plaintext shell initialization files - In profile backups and synchronization systems - In files often readable by other local tooling - Potentially in process inspection data whi ...[truncated 966 chars]
Remediation
View remediation

other

Warning
Location
scripts/upload_image.py:115
Finding

User Images Are Uploaded With Public-Read Access and No Expiration or Deletion Control

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:30
Finding

Credential-Handling Onboarding Flow Uses Unpinned Runtime Dependencies

Content
View full analysis
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" ) ``` ### Technical Analysis The package names are installed without pinned versions, hashes, a lockfile, or an explicitly trusted package index. Onboarding handles phone numbers, verification codes, access tokens, refresh tokens, API keys, account data, and payment QR content. Any imported dependency executes in the same process and can access those values. There is no evidence that the named packages are themselves malicious. The risk arises from asking users to resolve mutable third-party packages at runtime in a security-sensitive workflow. ### Attack Path 1. The environment lacks `requests`, `qrcode`, or Pillow. 2. The script displays an installation command. 3. The user executes the unpinned `pip install` command. 4. The package manager resolves whatever version the configured index currently serves. 5. A compromised package release, package index, dependency, or local package source is installed. 6. The package is imported into onboarding and executes with access to authentication and payment-related ...[truncated 422 chars]
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 (29)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The request forwards multiple environment-derived values, including SESSION_ID, MESSAGE_ID, MODE_ID, APP_NAME, and a configurable gateway base URL, directly into an outbound HTTP request. In this skill context, that creates a real exfiltration and SSRF-style risk if the runtime environment is attacker-influenced, because sensitive metadata and the API key-authenticated request can be sent to an arbitrary host via LINKFOX_TOOL_GATEWAY.

Content

Scanner excerpt · scripts/geekbi_temu_goods_image_search.py (reported line 166)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
94% confidence
Finding

The POST target is derived from environment-controlled base URLs, so a caller who can set LINKFOX_LOGIN_API_URL or LINKFOX_AGENT_USER_API_URL can redirect SMS login, access tokens, refresh tokens, and related account data to an attacker-controlled server. In a skill/onboarding context this is especially dangerous because the code handles authentication material and transmits it automatically without validating destination hosts.

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 URL is built from environment-controlled base configuration and then used by urllib to send authenticated requests containing the API key and session metadata. If an attacker can influence LINKFOX_AGENT_API_URL or LINKFOX_TOOL_GATEWAY, they can exfiltrate credentials and steer billing or account operations to an unintended endpoint.

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: 'req' from os.environ.get (line 74, 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="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            result = json.loads(response.read().decode("utf-8"))
    except HTTPError as exc:
        raise RuntimeError(

Tainted flow: 'req' from os.environ.get (line 74, 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 128)May include surrounding context.

python
method="PUT",
    )
    try:
        with urlopen(req, timeout=120) as response:
            if response.status not in (200, 201):
                raise RuntimeError(f"Image upload failed with HTTP {response.status}")
    except HTTPError as exc:

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented workflow requires uploading user-provided images to LinkFox OSS and calling external gateway services, yet the skill is presented primarily as a Temu search function. If this upload/export step is not made explicit at invocation time, users may disclose images, file metadata, and access patterns to a third party without informed consent.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented workflow requires uploading user-provided images to LinkFox OSS and calling external gateway services, yet the skill is presented primarily as a Temu search function. If this upload/export step is not made explicit at invocation time, users may disclose images, file metadata, and access patterns to a third party without informed consent.

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

md
User requests include “用这张图找 Temu 同款”, “找外观相似的 Temu 竞品”, and “search Temu products by this image”.

## Display Rules

1. Present a compact table with image, title, product ID, price, total/monthly sales, rating, reviews, hosting mode, and update time when available.
2. Display `thumbnail` images inline when the client supports images.

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 > `pay_ur

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file implements account onboarding, SMS login, API-key acquisition, plan listing, ordering, and payment support, which is materially unrelated to the declared Temu image-search skill purpose. Such scope expansion increases attack surface and creates an unjustified path to handle user identities, credentials, and financial operations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code can create orders, render payment QR codes, and query payment status despite the skill being described as a Temu image-search tool. This mismatch is dangerous because it introduces billing capability that users would not reasonably expect from the skill’s advertised function.

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 verification, account login, team selection, and API-token generation, all outside the stated Temu search scope. This is dangerous because it collects phone numbers and verification codes and turns them into reusable API credentials, greatly increasing the sensitivity of the component.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The upload sets x-oss-object-acl: public-read, making user-supplied images publicly accessible by URL. In the context of a product-image search skill, users may upload proprietary, private, or sensitive images, so automatically exposing them to the public internet creates a confidentiality risk and can leak business-sensitive or personal data.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares no explicit tool scope even though its documented behavior requires environment-variable access, network calls, and file writes. In an agent setting, missing least-privilege boundaries increases the chance that the skill is invoked with broader capabilities than users expect, enabling unintended data access or side effects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs the agent to automatically send feedback under broad conditions, including user dissatisfaction, praise, or anything that could be improved, without warning the user that interaction content may be transmitted. This can leak user prompts, behavioral signals, or workflow details to a secondary API beyond what is necessary to fulfill the request.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The document title and primary instructions are presented in Chinese, which establishes a specific language expectation for the skill documentation. The file does not indicate that users may choose another language or that the locale restriction is intentional and justified as region-specific.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The documented workflow sends user-provided image data and associated metadata to external services, first to LinkFox OSS and then to the LinkFox tool gateway. Although this is core to the skill's purpose and the docs include some constraints, it still represents real external transmission of potentially sensitive user content, which becomes risky if users upload private images or if consent/data-handling boundaries are unclear.

Content

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

md
LINKFOX_OSS_URL="$(printf '%s' "${LINKFOX_UPLOAD_RESULT}" | jq -r '.url')"
LINKFOX_CONTENT_TYPE="$(printf '%s' "${LINKFOX_UPLOAD_RESULT}" | jq -r '.contentType')"

curl --max-time 150 -X POST "${LINKFOX_TOOL_GATEWAY}/geekbi/temu/goodsImageSearch" \
  -H "Authorization: ${LINKFOX_AGENT_API_KEY:-$LINKFOXAGENT_API_KEY}" \
  -H "Content-Type: application/json" \
  -H "User-Agent: LinkFox-Skill/2.0" \

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest describes a narrowly scoped skill for searching visually similar products on Temu from an image. Lines L155-L175 add a distinct capability to POST user-feedback content to an external feedback API, which is not necessary to perform image-based Temu search and is not declared as part of the skill's purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The onboarding flow instructs operators to collect and pass a user's phone number and verification code to a script, but it provides no explicit consent, minimization, retention, or handling guidance for this personal data. In a support/onboarding context, this can lead to unnecessary collection of sensitive identifiers and one-time codes by the operator or system, increasing privacy and account-takeover risk if mishandled.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instructions tell users to persist the API key into shell startup files or permanent environment settings without warning that this writes a long-lived credential to local configuration files. If those files are readable by other users, synced, backed up, or later shared, the key can be exposed and abused to access the service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

Successful API responses are cached on disk for 24 hours under the working directory without explicit user awareness. This expands the exposure window for potentially sensitive commercial data and can leak prior query results to other local users, processes, or later sessions sharing the same filesystem.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script always writes the full API response to the local session data directory before deciding what to show the user. Because this skill handles product-search results that may include business-sensitive fields such as supply price, inventory, and shop data, persistent local storage without just-in-time disclosure or opt-in increases the risk of unintended retention and later exposure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file's user-facing help text and operational strings are entirely in Chinese, and the login flow is fixed to domestic phone numbers and area code +86. There is no indication that the user can choose language or locale, nor that the restriction is explicitly documented as a region-specific opt-in tool.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · 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 = ""

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The generated API key is printed to stdout in JSON, which may be captured by logs, agent transcripts, shell history tooling, or downstream integrations. In a hosted skill environment, this can expose reusable credentials beyond the intended user.

Content

No source excerpt is available for this finding.