Back to skill

Security audit

Shopee-店铺优惠券

Security checks for vulnerabilities and agentic risk

Overview

The skill does manage Shopee vouchers, but it also handles account credentials, billing flows, destructive voucher actions, and local response storage in ways users should review before installing.

Install only if you are comfortable giving this skill access to LinkFox/Shopee voucher operations and related LinkFox account billing workflows. Use it in a trusted environment, avoid overriding LinkFox endpoint environment variables, confirm delete/end/update actions explicitly before running them, and prefer a secret manager or per-session environment variable over writing API keys into shell startup files. Treat saved linkfox response files as sensitive business data and remove them when no longer needed.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_shopee_voucher_common.py:18
Finding

Credential Exfiltration Through Unrestricted Service Endpoint Overrides

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", }, 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 "" return {"error": f"HTTP {e.code}: {e.reason}", "details": body} except URLError as e: return {"error": f"Connection failed: {e.reason}"} ``` The onboarding implementation similarly accepts unrestricted endpoint overrides: ```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_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") ``` ```pytho ...[truncated 2894 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shopee_voucher_common.py:183
Finding

Unsafe Persistence of Complete API Responses and Path Traversal Through SESSION_ID

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 fallback = os.path.abspath(candidates[-1]) _LF_SESSION_CACHE["_root"] = fallback return fallback ``` ```python def _lf_session_id(ts: float) -> 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): """Persist the complete response under 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 = ...[truncated 3242 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:468
Finding

API Keys Exposed Through Standard Output and Plaintext Shell Profiles

Content
View full analysis
dict: masked = _mask_phone(phone) if not re.fullmatch(r"\d{11}", phone): return {"error": f"login: invalid phone number format: {phone}", "phone": masked} if not re.fullmatch(r"\d{4,8}", code): return {"error": f"login: invalid verification-code format: {code}", "phone": masked} lg = _login_v3(phone, code, channel) if "error" in lg: return {"error": lg["error"], "phone": masked} if lg.get("is_new_user"): lbt = _login_by_token(lg["access_token"], lg["refresh_token"]) if "error" in lbt: print(f"{TAG} {lbt['error']}", file=sys.stderr) info = _fetch_user_info_v3(lg["access_token"], lg["user_id"]) if "error" in info: return {"error": info["error"], "phone": masked} tok = _get_or_generate_api_token(lg["access_token"], lg["user_id"], info["group_id"]) if "error" in tok: return {"error": tok["error"], "phone": masked} return { "api_key": tok["api_key"], "phone": masked, "group_id": info["group_id"], "member_id": info["member_id"], "source": tok["source"], "nick_name": lg.get("nick_name", ""), "team_name": info.get("team_name", ""), "is_new_user": lg.get("is_new_user", False), } ``` ```python def _emit(obj: dict) -> 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 (source: {r['source']})", file=sys.stderr) return 0 return 1 ``` The onboarding documentation recommends pe ...[truncated 2171 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:162
Finding

Unpinned Runtime Dependency Installation Guidance

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} os.makedirs(out_dir, exist_ok=True) png_path = os.path.join(out_dir, f"qr-{int(time.time() * 1_000_000)}.png") qr = qrcode.QRCode(border=1) qr.add_data(content) qr.make(fit=True) qr.make_image(fill_color="black", back_color="white").save(png_path) buf = io.StringIO() qr.print_ascii(out=buf, invert=True) return {"png_path": png_path, "ascii_qr": buf.getvalue()} ``` ```python def _require_requests() -> None: if requests is None: raise RuntimeError("Missing requests dependency; run: pip install requests") ``` ### Technical Analysis The application tells users to install mutable package names directly from pip without: - Version pins - Hash verification - A lock file - A documented trusted package index - A reproducible environment specification No typo-squatted package name was identified, and the code does not automatically execute pip. However, following the guidance resolves whichever package versions the configured index currently serves. Installation and import of third-party Python packages can execute package-controlled code. ### Attack Path 1. The runtime lacks `requests`, `qrcode`, or `Pillow`. 2. The script instructs the user to run an unpinned `pip install` command. 3. The user executes the command in an environment using a compromised, malicious, or incorrectly configured package index, or resolves a future compromised release. 4. Package installation hooks or subsequently imported package code e ...[truncated 566 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (30)

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

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The code builds outbound request destinations from environment-controlled base URLs and then sends sensitive data 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 authentication and token flows to an attacker-controlled server and exfiltrate credentials or manipulate onboarding responses.

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 an environment-derived base URL and attaches the LinkFox API key in the Authorization header before calling urlopen. A hostile or misconfigured environment can redirect these authenticated requests to an attacker-controlled endpoint, causing API key leakage and unauthorized use of the account or team resources.

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

If the skill actually includes phone-login, SMS, account lookup, subscription, payment, or QR-code flows while presenting itself as a Shopee voucher manager, that is a serious deceptive-scope issue. Hidden auth, billing, or payment capabilities materially increase the risk of credential harvesting, unauthorized account actions, or monetization abuse under a benign-seeming trigger surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill actually includes phone-login, SMS, account lookup, subscription, payment, or QR-code flows while presenting itself as a Shopee voucher manager, that is a serious deceptive-scope issue. Hidden auth, billing, or payment capabilities materially increase the risk of credential harvesting, unauthorized account actions, or monetization abuse under a benign-seeming trigger surface.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The activation criteria are broad enough to trigger on general authorized-store management requests even when the user did not explicitly ask for voucher operations. In a skill that includes destructive actions like ending or deleting vouchers, overbroad triggering can lead to unintended invocation and harmful business changes.

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
证码后:`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
98% confidence
Finding

This skill is declared as a Shopee voucher-management integration, but the file implements unrelated account onboarding, SMS login, API key issuance, package purchasing, and payment/order handling. That scope mismatch is dangerous because users or hosts invoking a voucher skill would not reasonably expect credential collection and billing capabilities, increasing the risk of overprivileged behavior and covert account/token access.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file includes package browsing, order creation, payment URL handling, and QR-code rendering, none of which are justified by a Shopee voucher-management skill. This unnecessary billing functionality expands the attack surface and could be abused to trigger purchases, social-engineer payments, or mix commerce flows into a context where users expect only voucher administration.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code can retrieve or generate API tokens for a user group, which is a privileged capability unrelated to managing Shopee store vouchers. In the context of a voucher skill, this materially increases danger because a compromised or misused skill could mint reusable credentials that grant broader platform access beyond the user’s expected action.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
81% confidence
Finding

The skill declares capabilities that involve environment access, file writes, network use, and shell execution, but it does not define an explicit tool scope such as allowed-tools or permissions. That increases the attack surface because an invoking agent may grant broader capabilities than are necessary, making misuse or accidental overreach more likely.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The instruction to always write full API responses into session-linked files under the project directory creates a persistent data-retention channel that may expose shop data, identifiers, or operational metadata to other users, tools, or later tasks. Because the storage path is predictable and tied to session structure, the risk is amplified in shared workspaces or repos where artifacts may be committed or indexed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill exposes destructive operations such as delete_voucher and end_voucher without documenting a confirmation or warning step. In agent-driven workflows, omission of a confirmation requirement increases the chance of accidental irreversible changes to live promotions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation exposes destructive operations such as delete_voucher and end_voucher for live store data without any caution, confirmation guidance, or operational safeguards. In an agent skill context, this increases the chance that an LLM or user will invoke irreversible business actions on production vouchers accidentally, causing loss of promotions or unintended disruption to a merchant's storefront.

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


curl 示例

bash
curl -X POST ${LINKFOX_TOOL_GATEWAY}/shopee/developerProxy \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The document exposes a destructive voucher deletion capability and provides direct invocation examples, but it does not warn that the action is irreversible or require any explicit confirmation step. In an agentic context, this increases the chance that a user or downstream agent triggers deletion unintentionally, causing loss of active promotions and business disruption for the authorized Shopee store.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This markdown file presents the operational instructions and usage details entirely in Chinese, with no indication that the user can choose another language or that the locale restriction is intentional. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The onboarding instructions explicitly tell the operator to collect a user's phone number and use it to register/login via a script, but provide no consent, privacy notice, retention limits, or handling safeguards. In a support/onboarding context this creates unnecessary exposure of personal data and increases the risk of improper collection, logging, or reuse of the phone number and verification code.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The markdown recommends persisting an API key into shell startup files or Windows environment settings without warning that this stores credentials on disk and may expose them to other local users, backups, shell history, or support tooling. While common operational guidance, embedding long-lived secrets in profile files increases credential leakage risk if the host is shared or compromised.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/_shopee_voucher_common.py (reported line 41)May include surrounding context.

python
print(f"DEPENDENCY_MISSING: {json.dumps(payload, ensure_ascii=False)}", file=sys.stderr)
        sys.exit(DEPENDENCY_EXIT_CODE)
    try:
        result = subprocess.run(
            [sys.executable, str(checker)],
            capture_output=True,
            text=True,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file contains user-facing natural-language text exclusively in Chinese, including the docstring guidance and the stderr message "API Key 未配置". This imposes a specific language on users without any visible choice or opt-in, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

emit_result writes the full serialized API response to local disk under a predictable workspace structure, while this voucher skill handles store tokens, voucher data, and developer-proxy responses that may contain sensitive business or credential material. Persisting full responses without minimization, encryption, or explicit disclosure increases the risk of local data exposure, cross-session leakage, and unintended retention of secrets.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Beyond storage, the helper also summarizes and prints response structures and sample list entries, which can expose sensitive voucher-management data in stdout/log streams. In the context of a Shopee voucher/admin skill that interacts with developerProxy and token-resolution endpoints, logs may contain commercially sensitive campaign data or secrets and become accessible to operators, other tools, or later sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code sends query parameters and/or request bodies to an external developer proxy, potentially including shop or merchant identifiers and arbitrary POST content. While the module docstring states the purpose at a high level, there is no confirmation prompt, logging, or explicit warning in the file that user-provided data will be transmitted over the network.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring and command descriptions are entirely in Chinese, and later user-facing help and status/error messages also assume Chinese. This enforces a specific language/locale for all users without any opt-in or alternative, which matches the language-policy violation criteria.

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 = ""