Back to skill

Security audit

Shopee-店铺授权

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches Shopee authorization use, but it adds under-scoped outbound reporting, credential-bearing configurable endpoints, and broad local retention of sensitive authorization data.

Install only after reviewing the publisher and deciding whether you accept LinkFox account access, local response storage, clipboard/file handling of authorization URLs, billing-order capability, and automatic feedback reporting. Use a clean environment with trusted LINKFOX_* URL variables, avoid shared machines, inspect/delete generated linkfox cache files after use, and do not provide phone codes or payment confirmation unless you explicitly intend to set up or purchase LinkFox service access.

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

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:178
Finding

Silent external feedback reporting redirects the Agent beyond the declared task

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/authorize_url.py:25
Finding

API credentials can be transmitted to an arbitrary environment-controlled origin

Content
View full analysis
dict: api_key = get_api_key() data = json.dumps(params).encode("utf-8") req = Request( API_ENDPOINT, data=data, headers={ "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/1.0", }, method="POST", ) ``` The same pattern is used by the authorized-store and token-status clients. Onboarding similarly accepts configurable bases: ```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 scripts attach API keys, login access tokens, refresh tokens, or user identifiers to requests whose origins can be completely replaced through environment variables. No URL parsing, HTTPS enforcement, trusted-host allowlist, or development-mode gate is applied. Environment overrides can be useful for testing, but credentials must not be sent merely because a variable contains a syntactically usable URL. A compromised launcher, poisoned project environment, CI configuration error, or local attacker able to influence e ...[truncated 1272 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_token_status_output.py:24
Finding

Shallow token filtering can persist and print nested credentials

Content
View full analysis
dict: out = dict(result) out.pop("accessToken", None) out.pop("refreshToken", None) return out ``` The filtered object is then persisted and potentially printed: ```python result = call_api(params) result = strip_raw_tokens(result) emit_result(result, lf_inline_flag()) print_status_note(result) ``` ### Technical Analysis The filter removes only two exact keys from the top level of a dictionary. It does not inspect nested dictionaries or lists and does not recognize alternate credential names such as `access_token`, `refresh_token`, `token`, `apiToken`, `api_key`, or differently cased variants. The documentation states that the endpoint is status-only, but client-side protection should not trust that invariant. A server regression, error wrapper, proxy behavior, or compromised response could place credentials under a field such as `data`. The current filter would pass those values directly to `emit_result`, which stores the complete object and prints it when small enough or when `--inline` is used. ### Attack Path 1. The store-token endpoint returns a response such as: ```json { "data": { "accessToken": "sensitive-token", "refreshToken": "sensitive-refresh-token" } } ``` 2. `strip_raw_tokens` checks only the outer dictionary and finds neither key. 3. The nested tokens remain in the result. 4. `emit_result` writes them to a JSON file. 5. The tokens may also be printed to stdout and enter terminal logs or Agent context. 6. A local user, process, log collector, or downstream Agent component retrieves and reuses them. ### Impact Assessment Exposed access tokens may permit Shopee or LinkFox operations within the token’s scope and lifetime. Refresh-token exp ...[truncated 267 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/authorize_url.py:121
Finding

Shopee OAuth authorization URLs are automatically copied and stored insecurely

Content
View full analysis
bool: plat = platform.system() try: if plat == "Windows": p = subprocess.run(["clip.exe"], input=url, text=True, check=True, timeout=5) return p.returncode == 0 if plat == "Darwin": p = subprocess.run(["pbcopy"], input=url, text=True, check=True, timeout=5) return p.returncode == 0 for cmd in (["xclip", "-selection", "clipboard"], ["xsel", "--clipboard", "--input"], ["wl-copy"]): try: p = subprocess.run(cmd, input=url, text=True, check=True, timeout=5) if p.returncode == 0: return True except (FileNotFoundError, subprocess.CalledProcessError): continue return False except Exception: return False ``` ### Technical Analysis The OAuth URL contains a state parameter and represents an active authorization workflow. The script automatically places it in the system clipboard and writes it to a predictable filename. It does not r ...[truncated 1481 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_lf_output.py:22
Finding

Complete API responses are retained with weak permission and temporary-directory controls

Content
View full analysis
str: cached = _LF_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")) candidates.append(os.path.join(_lf_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) _LF_SESSION_CACHE["_root"] = root return root ``` ```python def emit_result(result, slug=SLUG, inline=False): """Persist the complete response and summarize large output.""" 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) print(f"Saved full response: {out} ({len(serialized)} bytes)") except OSError as e ...[truncated 1995 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (38)

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

Critical
Category
Data Flow
Confidence
92% confidence
Finding

The destination URL is partially controlled by environment variables, allowing requests containing the authorization API key to be redirected to an arbitrary host. In an agent or multi-tenant runtime, a poisoned environment could exfiltrate credentials and all submitted authorization parameters to attacker infrastructure.

Content

Scanner excerpt · scripts/authorize_url.py (reported line 58)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: 'req' from os.environ.get (line 42, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
93% confidence
Finding

The request destination is derived from environment variables (LINKFOX_TOOL_GATEWAY or SHOPEE_API_BASE_URL) and then used directly in urlopen with the Authorization API key attached. If an attacker can influence the runtime environment, they can redirect this request to an attacker-controlled server and exfiltrate the credential, making this an SSRF-style credential leakage issue. In a store-authorization skill, this is especially sensitive because the response may also reveal authorized store metadata.

Content

Scanner excerpt · scripts/authorized_stores.py (reported line 53)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
95% confidence
Finding

The code allows base URLs for login and agent-user API calls to be overridden by environment variables, then sends SMS login data, access tokens, refresh tokens, and API-token generation requests to those derived endpoints. If an attacker controls the runtime environment, they can redirect these credential-bearing requests to an attacker server and capture sensitive authentication material.

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

The gateway URL is also derived from environment variables and used to send authenticated requests with the LinkFox API key in the Authorization header. In a hostile skill/runtime environment, this can exfiltrate the API key and redirect account, package, and order operations to attacker-controlled infrastructure.

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 44, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The request destination is derived from environment variables (LINKFOX_TOOL_GATEWAY or SHOPEE_API_BASE_URL) and then used directly in urlopen. If an attacker can influence the runtime environment, they can redirect this script to an arbitrary endpoint and cause the Authorization API key and store authorization query data to be sent to an attacker-controlled server, resulting in credential exfiltration and possible SSRF-style outbound access.

Content

Scanner excerpt · scripts/store_tokens.py (reported line 55)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

Claiming support for authorization flow, shop binding, and authorized-store queries while only supporting narrower token/status lookup is a material capability overstatement. In agent systems, such overclaiming is a security issue because it broadens activation and can prompt unnecessary collection of identifiers or interaction with sensitive account state without actually fulfilling the stated task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Claiming support for authorization flow, shop binding, and authorized-store queries while only supporting narrower token/status lookup is a material capability overstatement. In agent systems, such overclaiming is a security issue because it broadens activation and can prompt unnecessary collection of identifiers or interaction with sensitive account state without actually fulfilling the stated task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Claiming support for authorization flow, shop binding, and authorized-store queries while only supporting narrower token/status lookup is a material capability overstatement. In agent systems, such overclaiming is a security issue because it broadens activation and can prompt unnecessary collection of identifiers or interaction with sensitive account state without actually fulfilling the stated task.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Claiming support for authorization flow, shop binding, and authorized-store queries while only supporting narrower token/status lookup is a material capability overstatement. In agent systems, such overclaiming is a security issue because it broadens activation and can prompt unnecessary collection of identifiers or interaction with sensitive account state without actually fulfilling the stated task.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger rule explicitly allows activation even when key terms like Shopee or authorization are absent, making accidental or adversarial invocation much more likely. Over-broad routing is dangerous because it can pull unrelated conversations into a skill that performs network calls, filesystem writes, or account-sensitive operations, expanding exposure without clear user intent.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 31)May include surrounding context.

md
- If the user needs both capabilities, obtain two fresh authorization URLs and explain that both authorizations must be completed.
- Authorization URLs expire after one hour, so obtain a new URL for every authorization attempt.

When calling `developerProxy`, pass the Shopee API path plus `shopId` or `merchantId`. Do not pass `appType` or an access token. The service routes `api/v2/ads/**` through the AD application and all other `api/v2/**` paths through the ERP application.

## 可用脚本

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
### 3. 查询授权状态 — `/shopee/storeTokens`

只返回授权状态/元数据,**不返回**原始 access token 或 refresh token(脚本侧也会剥离)。

**Request**(`shopId` 与 `merchantId` 二选一):
| 参数 | 类型 | 必填 | 默认 | 说明 |

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
证码后:`python scripts/onboarding.py login <phone> <code>`(workbuddy 宿主加 `--channel workbuddy`)
   - 拿到 `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 account onboarding, SMS login, billing, and API-key provisioning, while the manifest claims Shopee store authorization and management. This mismatch is dangerous because users and reviewers may grant trust and permissions under false pretenses, enabling credential collection and unrelated account operations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The ability to purchase LinkFox plans and generate payment QR codes is unjustified by the advertised Shopee authorization purpose. In this context, unrelated monetization features are especially suspicious because they can manipulate users into financial actions they did not intend when invoking a store-binding skill.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code creates purchase orders and renders payment QR codes, which is materially outside the stated Shopee authorization/query scope. Hidden payment functionality increases the risk of unauthorized charges, deceptive user flows, and abuse of trust in a marketplace authorization skill.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The login flow obtains or generates a LinkFox API key and returns it to the caller, which is unrelated to Shopee store authorization. This creates a clear risk of credential harvesting and privilege expansion under a misleading skill description.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill advertises file writing, shell, environment, and network-capable behavior but declares no explicit tool scope or permission boundary. In an agent setting this increases the blast radius of prompt-triggered actions, because the model may invoke sensitive capabilities without a least-privilege contract visible to reviewers or enforcement layers.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent to always persist full API responses to session-scoped files, which may include store identifiers, authorization state, account metadata, and other data beyond what is needed for the reply. Unnecessary retention increases the chance of later unauthorized access, cross-task leakage, or accidental inclusion of sensitive information in subsequent agent context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The skill defines cn as the default region, which imposes a locale-specific choice unless the user explicitly overrides it. Because the file serves multilingual usage and does not state a justification for defaulting all users to the China cross-border flow, this is a natural-language locale policy concern.

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 174)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 document instructs operators to collect a user's phone number and process login/registration flows via a script, but it does not require explicit user consent, minimization, masking, retention limits, or a privacy notice. This creates a real privacy and account-security risk because operators may handle sensitive identifiers and one-time codes in ad hoc ways that expose personal data or facilitate unauthorized account access.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The helper serializes and persistently stores full API responses to disk and also updates session indexing metadata. In a Shopee store authorization skill, API responses can reasonably contain access tokens, shop identifiers, account metadata, or other sensitive business data, so writing them unredacted to broadly chosen local paths creates an unnecessary data-retention and exposure risk beyond the stated authorization/query function.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill writes complete response payloads to disk automatically without any user-facing notice, consent, or indication that sensitive authorization data will be retained. Because this skill handles store authorization and account-linking workflows, silent persistence can capture credentials, tokens, shop data, and internal business information that users would not expect to be stored locally.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This Python file contains natural-language strings and comments in Chinese, including API key guidance and later runtime messages, but does not offer the user any language selection or indicate that the skill is intentionally China-only. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.