Back to skill

Security audit

Shopee-店铺限时特卖

Security checks for vulnerabilities and agentic risk

Overview

This Shopee flash-sale skill is mostly coherent, but it handles store authority, account credentials, billing, and local response logs with enough unsafe scoping to require Review before install.

Review this skill carefully before installing. Use it only in a controlled environment, keep LINKFOX_* endpoint variables unset unless you trust the destination, avoid running it where SESSION_ID or workspace paths can be attacker-controlled, and treat saved linkfox response files as sensitive merchant data. Require explicit human confirmation before create, update, delete, or payment-order commands.

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_shop_flash_sale_common.py:18
Finding
Environment-Controlled Endpoints Can Exfiltrate Authentication Credentials<![CDATA[ ## Vulnerability Details **File Location**: `scripts/_shopee_shop_flash_sale_common.py:18-24, 64-91`; `scripts/onboarding.py:68-89, 190-197, 225-246, 399-453` **Vulnerability Type**: Credential disclosure through unrestricted endpoint configuration **Risk Level**: High ### Vulnerable Code ```python API_BASE_URL = ( os.environ.get("LINKFOX_TOOL_GATEWAY") or os.environ.get("SHOPEE_API_BASE_URL") or "https://tool-gateway.linkfox.com" ).rstrip("/") STORE_TOKENS_ENDPOINT = f"{API_BASE_URL}/shopee/storeTokens" DEVELOPER_PROXY_ENDPOINT = f"{API_BASE_URL}/shopee/developerProxy" ``` ```python def call_api(endpoint: str, params: dict) -> 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")) ``` The onboarding implementation similarly accepts unrestricted endpoint overrides: ```python 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") ``` It then sends authentication data to those destinations: ```python def _headers(source: str, origin_host: str, *, access_token: str = "", user_id: str = "", group_id: str = "") -> dict: h = { "Accept": "application/json, text/plain, */*", "Content-Type": "application/json;charset=UTF-8", "Origin": f"https://{origin_host}", "Referer": f"https://{origin_host}/", "source": source, "User-Agent": UA, } if access_token: h["authorization"] = access_token h["uid"] = _uid_header(a ...[truncated 2521 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Allowlist the exact production hosts that may receive credentials, including: - `tool-gateway.linkfox.com` - `api.linkfox.com` - `agent-api.linkfox.com` 2. Parse configured URLs with a standard URL parser and require: - The `https` scheme - An exact approved hostname - No embedded username or password - No unexpected query string or fragment - An approved port, normally 443 3. Prevent cross-origin redirects when authorization headers or tokens are present. 4. Reject IP literals and hostname suffix tricks such as `tool-gateway.linkfox.com.attacker.example`. 5. If custom endpoints are needed for development, require an explicit development-mode switch and prohibit production credentials in that mode. 6. Keep endpoint overrides disabled by default and document their security implications. 7. Add automated tests proving that HTTP URLs, unapproved domains, malformed URLs, and redirect-based credential forwarding are rejected. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shopee_shop_flash_sale_common.py:216
Finding
Unsanitized SESSION_ID Allows Output Path Traversal<![CDATA[ ## Vulnerability Details **File Location**: `scripts/_shopee_shop_flash_sale_common.py:216-222, 315-329`; `scripts/onboarding.py:153-159` **Vulnerability Type**: Filesystem path traversal through an environment-derived path component **Risk Level**: Medium ### Vulnerable Code ```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"] ``` The unvalidated value is incorporated into the output path: ```python 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 workflow contains the same pattern: ```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 directory name. It is not restricted to a safe character set, and the resolved output path is not verified to remain below the intended `linkfox/<date>` directory. On common platforms, values containing `..` path components can escape the intended session directory. An absolute path may also cause `os.path.join()` to discard preceding components. The Skill then creates directories and writes r ...[truncated 1390 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate `SESSION_ID` before using it as a path component. For example, permit only `[A-Za-z0-9._-]{1,64}`. 2. Explicitly reject: - Absolute paths - `.` and `..` - Path separators - Drive prefixes on Windows - NUL characters and control characters 3. Resolve the destination and verify containment before creating it: ```python base = (Path(root) / date_str).resolve() destination = (base / validated_session_id).resolve() if destination != base and base not in destination.parents: raise ValueError("SESSION_ID escapes the output directory") ``` 4. Apply equivalent validation in both the shared response writer and `onboarding.py`. 5. Add tests covering Unix traversal, Windows separators, drive-qualified paths, absolute paths, and encoded or Unicode separator variants. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shopee_shop_flash_sale_common.py:181
Finding
Complete API Responses May Be Persisted in an Unsafe Temporary Directory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/_shopee_shop_flash_sale_common.py:181-207, 315-329` **Vulnerability Type**: Insecure storage and retention of potentially sensitive API data **Risk Level**: Medium ### Vulnerable Code ```python def _lf_root() -> 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 ``` Every complete result is then written without explicit restrictive permissions: ```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 ope ...[truncated 2166 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the system temporary-directory fallback and fail closed when the documented output location is unavailable. 2. Make persistent full-response storage opt-in, particularly for sensitive or destructive operations. 3. Create output directories with mode `0700` and files with mode `0600`, independent of the current umask. 4. Use atomic file creation with exclusive flags to prevent symlink and race-condition issues. 5. Redact tokens, authorization fields, personal data, and sensitive error content before persistence. 6. Implement configurable retention and secure cleanup. 7. Inform users clearly where data will be stored before writing it. 8. Keep implementation behavior consistent with `SKILL.md`; if fallback storage is retained, document it accurately and warn users. ]]>

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:163
Finding
Onboarding Recommends Installation of Unpinned Third-Party Packages<![CDATA[ ## Vulnerability Details **File Location**: `scripts/onboarding.py:163-166, 184-187` **Vulnerability Type**: Unpinned dependency installation and supply-chain exposure **Risk Level**: Low ### Vulnerable Code ```python def render_qr(content: str, out_dir: str) -> dict: try: import qrcode except ImportError: err = "缺少 qrcode 依赖,请运行: pip install qrcode pillow" print(f"{TAG} render_qr: {err}", file=sys.stderr) return {"png_path": None, "ascii_qr": None, "error": err} ``` ```python def _require_requests() -> None: if requests is None: raise RuntimeError("缺少 requests 依赖,请运行: pip install requests") ``` ### Technical Analysis The onboarding workflow instructs users to install `requests`, `qrcode`, and `pillow` without version constraints, hashes, a lockfile, or a specified trusted package index. The package names shown are established packages rather than apparent typosquats, and the code does not automatically execute `pip`. Therefore, this is not evidence of an intentionally malicious dependency. However, following the instructions resolves whatever package version the active Python package index currently serves, making installations non-reproducible and vulnerable to a compromised index, malicious future release, or unsafe package-source configuration. ### Attack Path 1. A user invokes an onboarding operation without the required package installed. 2. The script instructs the user to run an unpinned `pip install` command. 3. The user’s pip configuration points to a compromised or attacker-controlled index, or a malicious package release is served under the expected name. 4. The user executes the suggested command. 5. Malicious package installation or import-time code runs with the privileges of the user performing the installation. ### Impact Assessment A compromised dependency can execute arbitrary code with the privileges of the Python environment or user account. It could access environment v ...[truncated 324 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Provide a version-controlled dependency file with exact versions. 2. Use hashes, for example through a requirements file generated with `pip-compile --generate-hashes`. 3. Document a trusted package index and recommend installation with hash verification enabled. 4. Publish and verify a software bill of materials for runtime dependencies. 5. Test supported dependency updates before changing pinned versions. 6. Prefer an isolated virtual environment rather than installation into a global Python environment. 7. Replace free-form installation instructions with a reproducible setup command referencing the audited lockfile. ]]>
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 (37)

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

Critical
Category
Data Flow
Content
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 = ""
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
Data Flow
Content
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
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
A second, more severe mismatch indicates behavior tied to SMS login, token issuance, account info, plan purchase, payment orders, QR rendering, and payment-status flows instead of Shopee Flash Sale management. This is dangerous because it crosses into account/payment infrastructure, potentially exposing credentials, billing actions, or identity flows under the cover of an unrelated e-commerce management skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
A second, more severe mismatch indicates behavior tied to SMS login, token issuance, account info, plan purchase, payment orders, QR rendering, and payment-status flows instead of Shopee Flash Sale management. This is dangerous because it crosses into account/payment infrastructure, potentially exposing credentials, billing actions, or identity flows under the cover of an unrelated e-commerce management skill.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Content
证码后:`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
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The file implements LinkFox account onboarding, SMS login, API key retrieval, subscription browsing, order creation, and payment QR generation, which are materially unrelated to a Shopee Shop Flash Sale API-forwarding skill. This scope mismatch is dangerous because it introduces credential collection and billing behaviors that users would not reasonably expect from the declared skill, increasing the chance of deceptive data harvesting or unauthorized purchases.

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
Order creation and QR payment rendering enable direct purchase flows inside a skill whose advertised function is Shopee flash-sale management. In context, this is more dangerous because users invoking a storefront automation skill are unlikely to expect hidden billing capabilities, creating risk of social engineering, surprise charges, or abuse of stored API credentials to initiate purchases.

Lp3

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding
The skill advertises capabilities that imply shell, network, environment access, and file writing, but it does not declare any explicit tool scope or permission boundaries. In an agent environment, missing scope constraints increases the chance the skill can invoke broader-than-necessary capabilities, making misuse or accidental data access harder to prevent and audit.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger condition is intentionally broad, allowing activation even when the user does not explicitly mention flash-sale keywords. Overbroad triggering can cause the wrong skill to run for general store-management requests, increasing the chance of unnecessary API calls, unintended side effects, or disclosure of store data in the wrong context.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill instructs the agent to always write complete API responses to disk, but does not warn about or limit storage of potentially sensitive business data such as campaign details, item metadata, shop identifiers, or operational history. Persisting full responses by default expands the data exposure surface beyond the immediate task and can leave sensitive records in local project directories.

Ssd 3

Medium
Confidence
90% confidence
Finding
Mandating that every API response be persisted in a session-organized local log creates systematic over-retention of user and store data. In agent environments, local logs may be accessible to other tools, later tasks, or repository workflows, so storing more data than needed increases confidentiality and compliance risk without clear necessity.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This markdown file describes creation, update, and deletion operations for Shop Flash Sale resources, including deleting activities or items, but it does not warn that these actions can alter or remove live shop promotion data. Under the markdown-specific warning criteria, behaviors affecting user data or system integrity should be disclosed clearly.

External Transmission

Medium
Category
Data Exfiltration
Content
---

## curl 示例

```bash
curl -X POST ${LINKFOX_TOOL_GATEWAY}/shopee/developerProxy \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation explicitly exposes a create operation for Shopee flash sale events and states to 'pass full body', but it does not warn that this action modifies live shop promotional configuration. In an agent skill context, missing mutation warnings and confirmation guidance can lead to unintended creation of real flash sale events, causing operational disruption, pricing/promotion mistakes, or unauthorized campaign changes on a connected store.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This documentation describes a destructive API operation that removes items from a flash sale, but it provides no warning about the irreversible business impact, no confirmation requirements, and no guidance to validate target IDs before execution. In an agent-driven workflow, that omission increases the chance of accidental or unauthorized destructive actions, especially because the skill is designed to trigger on natural-language requests related to Shopee flash sale management.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
This documentation exposes a destructive API operation that deletes flash sale data but provides no warning, confirmation flow, rollback note, or guardrails for human or agent-driven use. In an agent skill context, missing deletion safeguards increases the chance of unintended destructive actions against a live Shopee store, especially when the skill is designed to trigger on broad flash-sale management requests.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file’s operational instructions and parameter descriptions are primarily presented in Chinese, which effectively forces a specific language for users of the skill. The policy allows locale constraints only when users are given a choice or when the restriction is clearly documented and justified, neither of which appears here.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The document states this endpoint returns flash sale details by `flash_sale_id`, but the documented JSON inputs only include `shopId` or `merchantId` and omit the required business parameter. This can cause callers to issue malformed requests, retrieve no data, or build unsafe workarounds that guess or inject parameters outside the documented contract, increasing the chance of operational errors in a privileged commerce-management workflow.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documentation describes a state-changing operation that updates live flash sale settings but does not warn users that the action can modify production shop configuration. In an agent-driven context, this omission increases the chance of unintended or unauthorized business changes, such as altering active promotions, pricing windows, or campaign behavior for a real merchant account.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly instructs the agent to collect a user's phone number and use it to drive registration/login flows, but it provides no privacy notice, consent language, retention limits, or safe-handling guidance. In an agent context, this creates a real risk of unnecessary collection and exposure of personal data, especially if the number is transmitted, logged, or stored during support workflows.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The helper builds and sends POST requests to external endpoints using parameters that include shopId, merchantId, query strings, request bodies, and optionally access tokens. Although network access is central to the skill, this file does not provide any confirmation prompt or user-facing disclosure before transmitting that data.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The session logging and archival layer adds behavior beyond the core API proxy function by creating directories, metadata indexes, and durable local records of activity. This expands the skill's attack surface and data footprint, making sensitive operational data available outside the immediate request flow without clear necessity.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The helper writes full API responses to local files under predictable session directories, even though the skill is described as an API forwarding helper for Shopee Flash Sale operations. Those responses may contain sensitive business data, identifiers, tokens, or operational metadata, creating unnecessary local data retention and increasing exposure if the host is shared or later compromised.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
Persisting full API responses to disk without clear disclosure creates a confidentiality risk because returned data may include sensitive store details, pricing, inventory, or auth-related metadata. In the context of an e-commerce management skill, retaining such data locally is more dangerous because it concerns real merchant operations and may outlive the original user interaction.

Static analysis

No suspicious patterns detected.