Back to skill

Security audit

Shopee-商品详情

Security checks for vulnerabilities and agentic risk

Overview

The skill does perform Shopee lookup, but it also handles account login, API keys, paid-plan ordering, automatic feedback reporting, and broad local persistence with weak controls.

Install only if you are comfortable giving this skill a LinkFox API key, using LinkFox account/billing onboarding, and having lookup responses cached locally. Avoid entering phone/SMS codes through an agent unless you trust the publisher, do not persist API keys in shell startup files if a secret store is available, and do not use environment endpoint overrides outside a controlled development setup.

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 (6)

other

Warning
Location
SKILL.md:112
Finding

Automatic transmission of conversation-derived feedback without explicit consent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/shopee_product_detail.py:36
Finding

Sensitive credentials can be transmitted to arbitrary environment-controlled endpoints

Content
View full analysis
str: return ( os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com" ).rstrip("/") def get_api_url(): sys.path.insert( 0, os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "..", "_shared", ), ) 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", ""), "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", ) with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` The onboarding script applies the same pattern to more sensitive login endpoints at `scripts/onboarding.py:69-85`: ```python def _env_base(name: str, default: str, *fallbacks: str) -> str: for n in (name, *fallbacks): v = os.environ.get(n) if v: return v.rstrip("/") return default.rstrip("/") def _agent_base() -> str: return _env_base( "LINKFOX_AGENT_API_URL", "https://tool-gateway.linkfox.com", "LINKFOX_TOOL_G ...[truncated 2993 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:486
Finding

Complete API key is printed to stdout and recommended for plaintext 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} API key successfully obtained " f"(source: {r['source']})", file=sys.stderr, ) return 0 return 1 ``` The onboarding documentation at `references/onboarding.md:11-15` directs users to persist the returned key in shell startup configuration. The documented command pattern is equivalent to: ```bash echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc ``` ### Technical Analysis The onboarding command serializes the complete API key into stdout. Standard output is commonly captured by: - Agent transcripts - Terminal scrollback - CI logs - Shell wrappers - Debugging systems - Process orchestration logs The documented setup process also places the complete bearer credential directly in a shell command and a plaintext startup file. This can expose it through shell history, backups, synchronized dotfiles, support logs, or local users and processes that can read the file. Although obtaining an API key is part of onboarding, displaying and forwarding the entire secret is not the minimum necessary handling model. ### Attack Path 1. The user runs the phone and SMS-code login command. 2. The script obtains or generates an ...[truncated 848 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/onboarding.py:163
Finding

Onboarding directs users to install 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, } def _require_requests() -> None: if requests is None: raise RuntimeError( "Missing requests dependency; run: " "pip install requests" ) ``` The source messages instruct installation of `qrcode`, `pillow`, and `requests` without specifying reviewed versions or hashes. ### Technical Analysis Package installation can execute package build or installation logic with the current user's privileges. The project supplies no lock file, version constraints, package hashes, or trusted-index requirement. Consequently, installation resolves mutable package versions from whichever pip index is configured in the environment. This creates exposure to compromised releases, dependency confusion through an unsafe private index, index substitution, or future incompatible or malicious versions. The identified package names are not themselves demonstrated to be malicious. The issue is the unsafe and non-reproducible dependency acquisition process. ### Attack Path 1. A required module is absent. 2. The script instructs the user or agent to run the displayed pip command. 3. Pip resolves packages from the active package index configuration. 4. A compromised index, malicious mirror, or compromised package release supplies executable installation content. 5. Installation code executes with the invoking user's pri ...[truncated 528 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/shopee_product_detail.py:248
Finding

Unsanitized session identifier permits output-path traversal

Content
View full analysis
str: env = os.environ.get("SESSION_ID") if env: return env.strip() 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 ``` ### Technical Analysis `SESSION_ID` is used directly as a filesystem path component. The code does not reject: - Absolute paths - `..` traversal components - Path separators - Platform-specific drive or UNC paths - Excessively long values With `os.path.join`, an absolute `sid` can replace the preceding root components. Relative values containing traversal components can also escape the intended date and LinkFox directories. The code subsequently creates directories and writes metadata and full response files beneath the attacker-selected location. ### Attack Path 1. An attacker or untrusted launcher controls `SESSION_ID`. 2. The value is set to an absolute path or a path containing traversal components. 3. The user runs the product-detail script. 4. `_ensure_session` constructs a path outside the intended LinkFox root. 5. The script creates directories and writes `_meta.json` and product-response fi ...[truncated 702 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/shopee_product_detail.py:205
Finding

Full responses may be silently written to temporary or unexpected directories

Content
View full analysis
str: cached = _SESSION_CACHE.get("_root") if cached: return cached candidates = [] acpx = ( os.environ.get("ACPX_WORKSPACES") or "" ).strip() if acpx: acpx = acpx.split(os.pathsep)[0].strip() if acpx: candidates.append( os.path.join(acpx, "linkfox") ) candidates.append( os.path.join(os.getcwd(), "linkfox") ) candidates.append( os.path.join( os.path.expanduser("~"), "linkfox", ) ) import tempfile candidates.append( os.path.join( tempfile.gettempdir(), "linkfox", ) ) for root in candidates: try: os.makedirs(root, exist_ok=True) probe = os.path.join( root, ".write_probe", ) with open(probe, "w", encoding="utf-8") as f: f.write("") os.remove(probe) except OSError: continue root = os.path.abspath(root) _SESSION_CACHE["_root"] = root return root fallback = os.path.abspath(candidates[-1]) _SESSION_CACHE["_root"] = fallback return fallback ``` The implementation always writes the full response through `scripts/shopee_product_detail.py:338-345`: ```python serialized = json.dumps( result, ensure_ascii=False, indent=2, ) ts = int(time.time()) out_path = _resolve_output_path(ts) try: with open(out_path, "w") as f: f.write(serialized) print( f"Saved full response: {out_path} " f"({len(serialized)} bytes)" ) except OSError as e: print( f"Failed to save to {out_path}: {e}" ...[truncated 1860 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 (27)

Description-Behavior Mismatch

Critical
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file implements LinkFox account onboarding, SMS login, API key acquisition, plan listing, order creation, and payment QR generation, which is fundamentally unrelated to a Shopee public product-detail parser. This kind of capability mismatch is a strong indicator of deceptive or repurposed code and greatly increases the risk of credential harvesting, unauthorized account actions, and unwanted purchases under the guise of a harmless data lookup skill.

Content

No source excerpt is available for this finding.

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The code builds POST destinations from environment-controlled base URLs and then sends sensitive authentication material such as phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys to those endpoints. If an attacker can influence environment variables in the skill runtime, they can redirect requests to attacker-controlled infrastructure and exfiltrate credentials or payment/session data; this is especially dangerous because the skill’s stated purpose does not justify handling account-login secrets at all.

Content

Scanner excerpt · scripts/onboarding.py (reported line 196)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 244, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The gateway request path uses urllib with a URL derived from environment-configurable base addresses and attaches the API key in the Authorization header. An attacker who can set those environment variables can force authenticated requests to a malicious server, leading to credential leakage, account misuse, and exposure of order/account metadata.

Content

Scanner excerpt · scripts/onboarding.py (reported line 246)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 71, 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/shopee_product_detail.py (reported line 78)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documentation says the tool performs a straightforward public product lookup, but the detected behavior includes mandatory local persistence, 24-hour caching, transmission of environment metadata, and storage-path behavior inconsistent with the manifest. Hidden storage and metadata exfiltration materially change the privacy and security posture, especially when session identifiers or other environment values are sent remotely.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documentation says the tool performs a straightforward public product lookup, but the detected behavior includes mandatory local persistence, 24-hour caching, transmission of environment metadata, and storage-path behavior inconsistent with the manifest. Hidden storage and metadata exfiltration materially change the privacy and security posture, especially when session identifiers or other environment values are sent remotely.

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

python scripts/shopee_product_detail.py '{"productUrl":"https://shopee.sg/%28LENECT-OFFICIAL-STORE%29-Flash-I-Aurora-Dual-Highlighter-7.2g-COCOMO-i.9641401.29691169956"}'

text

## Display Rules

1. Lead with the listing name, item ID, shop, marketplace, current price, currency, stock, and public sold count.
2. Show current/original price and discount exactly as returned; do not convert currencies unless requested.

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

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module self-describes as a LinkFox onboarding CLI, directly contradicting the skill metadata that claims Shopee product-detail functionality. This inconsistency is a strong red flag for disguised behavior because it suggests the packaged code is not the code users would reasonably expect to run for the advertised skill.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code creates purchase orders and renders payment QR codes even though the skill is advertised as a Shopee product-detail lookup tool. This mismatch enables unauthorized or deceptive monetization flows and could trick users or host agents into initiating paid transactions unrelated to the requested task.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

A public Shopee product-detail reader should not need to send SMS verification codes or perform phone-based login, yet this code requests a phone number, transmits it externally, verifies codes, and retrieves API keys. In context, this looks like unjustified credential collection and account-token provisioning hidden inside an unrelated skill, making the behavior substantially more dangerous than similar code in a legitimate onboarding utility.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The documentation explicitly says writing to /tmp is forbidden and that a non-writable current directory should cause an error, but the code silently falls back to the home directory and then the temp directory. That mismatch undermines operator expectations and can lead to sensitive API responses being written into broader, less controlled locations than users were told.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill declares no explicit tool scope while the manifest and behavior imply access to environment variables, local file writes, and network calls. Missing least-privilege scoping makes it harder to constrain execution and increases the blast radius if the skill is misused or compromised.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Always saving complete responses under a session-based path creates a durable link between user activity and stored artifacts. Session-organized plain JSON files can expose sensitive workflow details to other users, processes, backups, or repository commits, especially in shared project directories.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill mandates writing full JSON responses into the current project directory but does not prominently warn users about persistence, discoverability by other tools, or privacy implications. Even if product data is public, saved responses may include user-provided URLs, session-correlated paths, and other metadata that can leak workflow context.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill is presented as a single-product read-only lookup, but it also instructs automatic reporting to a separate Feedback API. That creates an additional outbound data flow unrelated to the primary task, potentially transmitting user content or operational context without clear necessity or consent.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Automatic feedback submission is not required to fetch a public Shopee product page and therefore represents unjustified secondary processing. Unnecessary telemetry increases privacy risk and broadens the skill's external communication surface.

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

| 402 | 算力不足 | 按 SKILL.md 的「解决认证和算力问题」处理 | | 超时或上游异常 | 连接错误、5xx 或业务错误 | 告知用户;不要连续自动重试产生额外费用 |

curl 示例

bash
API_KEY="${LINKFOX_AGENT_API_KEY:-$LINKFOXAGENT_API_KEY}"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to collect a user's phone number and process it through a registration/login flow, but it provides no explicit consent language, privacy notice, retention limits, or data-handling safeguards. Because phone numbers and one-time codes are sensitive personal data and account-authentication material, this creates privacy and account-security risk if the agent prompts for or mishandles them.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's CLI description and user-facing messages are written in Chinese throughout, and there is no indication that users can opt into another language or locale. This can violate language/locale policy when a skill forces a specific language without user choice or documented regional justification.

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 196)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
87% confidence
Finding

The skill generates or fetches an API token and emits it in stdout JSON without any in-code warning, redaction, or explicit confirmation step. In a hosted agent environment, stdout may be logged, forwarded, or exposed to other components, so this can leak reusable credentials beyond the immediate user interaction.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description suggests it simply returns Shopee product details, but the implementation always persists full API responses, session metadata, and cache files locally. This creates an undisclosed data retention surface that may expose scraped business data, session linkage, and potentially sensitive response content to other local users, tools, or later processes.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The comment says small responses are output directly without file persistence, but the code always writes the full response to disk first. This is a security-relevant documentation mismatch because users and reviewers may assume ephemeral handling for small datasets when the tool actually retains everything locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script sends SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME from the environment to a remote endpoint without explicit disclosure during execution. While these are not secrets by themselves, they can enable cross-request correlation, reveal internal workflow metadata, and expand the privacy footprint beyond the apparent product lookup function.

Content

No source excerpt is available for this finding.