Back to skill

Security audit

Shopee-店铺商户

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly implements Shopee merchant lookups, but it also adds account login, payment, automatic feedback reporting, and plaintext data retention that users should review before installing.

Install only if you are comfortable sending Shopee merchant/account data and LinkFox credentials through LinkFox services, and review the bundled onboarding and payment flows before allowing them to run. Avoid untrusted environment overrides, treat phone numbers, SMS codes, API keys, merchant IDs, and saved response files as sensitive, and delete or protect the local linkfox output directory after use.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:113
Finding

Automatic Third-Party Feedback Reporting Alters Agent Behavior Without Explicit User Consent

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_shopee_merchant_common.py:18
Finding

Environment-Controlled API Endpoints Can Redirect Credentials and User Identifiers

Content
View full analysis
dict: api_key = get_api_key() data = json.dumps(params).encode("utf-8") req = Request( endpoint, data=data, headers={ "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/1.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", ""), }, method="POST", ) try: with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` The onboarding endpoints are similarly configurable: ```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", ) ``` Tokens and identifiers are then attached to requests: ```python def _headers(source: str, origin_host: str, *, access_token: str = "", ...[truncated 2868 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_shopee_merchant_common.py:217
Finding

Unsanitized SESSION_ID Allows Arbitrary Writable-Path Selection

Content
View full analysis
str: env = os.environ.get("SESSION_ID") if env: return env.strip() if "_auto" not in _LF_SESSION_CACHE: _LF_SESSION_CACHE["_auto"] = ( _lf_time.strftime("%H%M%S", _lf_time.localtime(ts)) + "-" + _lf_secrets.token_hex(3) ) return _LF_SESSION_CACHE["_auto"] ``` ```python def emit_result(result, slug=SLUG, inline=False): serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = _lf_time.time() date_str = _lf_time.strftime("%Y-%m-%d", _lf_time.localtime(ts)) sid = _lf_session_id(ts) root = _lf_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _lf_ensure_meta(root, session_dir, date_str, sid, ts) data_dir = os.path.join(session_dir, "data") os.makedirs(data_dir, exist_ok=True) out = os.path.join( data_dir, f"{slug}-{int(ts * 1_000_000)}.json", ) try: with open(out, "w", encoding="utf-8") as f: f.write(serialized) ``` The onboarding implementation has the same issue: ```python def session_dir() -> str: ts = time.time() sid = (os.environ.get("SESSION_ID") or "").strip() or ( time.strftime("%H%M%S", time.localtime(ts)) + "-" + secrets.token_hex(3) ) path = os.path.join( _linkfox_root(), time.strftime("%Y-%m-%d", time.localtime(ts)), sid, ) os.makedirs(path, exist_ok=True) return path ``` ### Technical Analysis `SESSION_ID` is treated as a trusted path component. It is not checked for absolute paths, path separators, `..` components, control characters, or excessi ...[truncated 1848 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:484
Finding

API Keys and Complete Merchant Responses Are Exposed Through Plaintext Output and Storage

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(来源: {r['source']})", file=sys.stderr, ) return 0 ``` Complete merchant responses are also stored in plaintext: ```python def emit_result(result, slug=SLUG, inline=False): """落盘完整响应到 linkfox///data/-.json;大响应只打印摘要。无缓存。""" serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = _lf_time.time() date_str = _lf_time.strftime("%Y-%m-%d", _lf_time.localtime(ts)) sid = _lf_session_id(ts) root = _lf_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _lf_ensure_meta(root, session_dir, date_str, sid, ts) data_dir = os.path.join(session_dir, "data") os.makedirs(data_dir, exist_ok=True) out = os.path.join( data_dir, f"{slug}-{int(ts * 1 ...[truncated 2442 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (44)

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The helper sends sensitive environment-derived values, including the API key and session/message metadata, to a network endpoint whose base URL can itself be overridden by environment variables. In a skill that proxies merchant/account data, this materially increases the risk of credential exfiltration and unauthorized disclosure if the runtime environment or endpoint configuration is compromised or attacker-controlled.

Content

Scanner excerpt · scripts/_shopee_merchant_common.py (reported line 88)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 ""

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The code sends authentication material and user data to URLs derived from environment-controlled base addresses without validating or pinning the destination host. If an attacker can influence environment variables in the runtime, they can redirect SMS login, token exchange, and API-key generation traffic to an attacker-controlled server and capture credentials or tokens.

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
96% confidence
Finding

Gateway requests are built from environment-controlled base URLs and sent with the API key in the Authorization header. An attacker who can set the environment can cause the tool to exfiltrate the LinkFox API key and subsequent account/order data to an external endpoint, turning this into credential theft and unauthorized API access.

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Claiming to retrieve Shopee merchant information while instead performing onboarding, billing, payment, or order-status operations is a serious scope violation. In this context, the mismatch is more dangerous because users querying merchant data may unknowingly trigger account or payment-related actions and disclose sensitive financial or authentication context.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Claiming to retrieve Shopee merchant information while instead performing onboarding, billing, payment, or order-status operations is a serious scope violation. In this context, the mismatch is more dangerous because users querying merchant data may unknowingly trigger account or payment-related actions and disclose sensitive financial or authentication context.

Content

No source excerpt is available for this finding.

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

The file implements LinkFox onboarding, SMS login, token handling, pricing, ordering, and payment QR generation, which is materially unrelated to the declared Shopee merchant-information skill. This scope mismatch is dangerous because users or orchestrators expecting read-only Shopee queries may instead trigger credential collection and account/payment workflows.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The order-creation flow initiates commercial purchases and renders payment QR codes, exceeding the manifest's expected merchant-info retrieval behavior. In the skill context, this is especially dangerous because it introduces real financial actions where users would reasonably expect passive data lookup only.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The login flow sends SMS codes, logs users in, fetches team metadata, and obtains or generates API tokens, none of which are necessary for Shopee merchant info retrieval. In this skill context, that makes the behavior more dangerous because it covertly adds credential acquisition and secret issuance capabilities under an unrelated feature label.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill advertises shell, network, environment, and file-write capable behavior but declares no explicit tool scope or permission boundaries. In a skill that handles merchant/account data and instructs writing outputs to disk, missing scope declarations increase the chance of overbroad execution and unintended access to sensitive local or remote resources.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger description is overly broad and can activate on loosely related merchant topics even when the user did not clearly request this specific skill. Because the skill accesses merchant/shop/account data, over-triggering raises the risk of unnecessary data access, wrong-tool execution, and privacy exposure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Internal contradictions about compute consumption reduce the user's ability to give informed consent and can lead agents to make unsafe autonomous decisions about retries or follow-up queries. In a paid API proxy context, this ambiguity is operationally and financially risky.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill states that full API responses are always written to local project storage without adequately warning that merchant data may include sensitive business, account, warehouse, or financial details. Persisting such data by default expands exposure beyond the immediate request and can leak information to later users, tools, commits, backups, or logs.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Always persisting full API responses to session-scoped local files creates durable plaintext retention of potentially sensitive merchant and user data. In this skill's context, that is especially dangerous because the data may include merchant identities, shop associations, warehouse locations, and prepaid account information that are unnecessary to retain after the task completes.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document states both that use may consume compute/quota and that the skill does not consume compute. Contradictory cost semantics can mislead users into approving actions they would otherwise avoid, and can cause repeated retries or unexpected billing when quota-sensitive operations are involved.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation explicitly directs users to send merchant-scoped data, access tokens, and API-key-authenticated requests through external Linkfox gateways, but it provides no warning about the sensitivity of those credentials or merchant identifiers. In a skill handling cross-border merchant account information, this omission can lead to accidental disclosure via misconfiguration, copied examples, client logs, or use in unsafe environments.

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


curl 示例

bash
export KEY=$LINKFOXAGENT_API_KEY

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The curl examples show real outbound requests containing an Authorization header, accessToken, and merchantId, but they do not warn that these values may be exposed through shell history, terminal logging, process inspection, CI logs, or copied support transcripts. Because the examples concern merchant and shop data, accidental leakage could expose account metadata and enable unauthorized API use if tokens or keys are reused.

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 operational documentation is written entirely in Chinese, including usage instructions and response guidance, with no indication that another language is available. This can violate language/locale policy when users are not given an explicit choice or opt-in for a specific language.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The onboarding guidance broadens behavior beyond the merchant-info skill’s stated purpose by instructing the agent to invoke a bundled onboarding flow whenever auth or billing errors occur. In a skill context, this can cause over-triggering into account-registration, payment, or credential-recovery actions that were not explicitly requested by the user, increasing the chance of unnecessary collection of sensitive data and unintended account changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instructions direct the workflow to request, handle, and transmit a user’s phone number and one-time verification code without any privacy warning, minimization guidance, or restrictions on storage/logging. Because phone numbers and OTPs are highly sensitive authentication data, collecting them inside a skill workflow creates account-takeover and privacy risks if mishandled, logged, or requested without strong user awareness.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/apis/get-shop-list-by-merchant.md (reported line 46)May include surrounding context.

md
"get_shop_list_by_merchant": {
        "path": "api/v2/merchant/get_shop_list_by_merchant",
        "method": "GET",
        "response_key": "getShopListByMerchant",
        "required": ['page_no', 'page_size'],
        "notes": 'Shops bound to merchant; page_size max 500',
    },

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/apis/get-warehouse-eligible-shop-list.md (reported line 44)May include surrounding context.

md
"get_shop_list_by_merchant": {
        "path": "api/v2/merchant/get_shop_list_by_merchant",
        "method": "GET",
        "response_key": "getShopListByMerchant",
        "required": ['page_no', 'page_size'],
        "notes": 'Shops bound to merchant; page_size max 500',
    },

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/_merchant_endpoints.py (reported line 27)May include surrounding context.

python
"get_shop_list_by_merchant": {
        "path": "api/v2/merchant/get_shop_list_by_merchant",
        "method": "GET",
        "response_key": "getShopListByMerchant",
        "required": ['page_no', 'page_size'],
        "notes": 'Shops bound to merchant; page_size max 500',
    },

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/_merchant_endpoints.py (reported line 46)May include surrounding context.

python
"get_shop_list_by_merchant": {
        "path": "api/v2/merchant/get_shop_list_by_merchant",
        "method": "GET",
        "response_key": "getShopListByMerchant",
        "required": ['page_no', 'page_size'],
        "notes": 'Shops bound to merchant; page_size max 500',
    },