Back to skill

Security audit

Shopee-店铺精选

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches a Shopee Top Picks integration, but it has review-worthy credential, billing, mutation, and local data persistence risks.

Install only if you are comfortable giving this skill access to LinkFox credentials and live Shopee Top Picks operations. Before use, avoid endpoint override environment variables unless you fully trust them, confirm every create/update/delete action manually, treat generated API keys as secrets, and periodically delete the saved linkfox response files if they may contain store or account data.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_shopee_top_picks_common.py:19
Finding

Credentials Can Be Redirected to Attacker-Controlled Network Endpoints

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")) ``` The onboarding flow independently supports configurable authentication destinations: ```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") ``` Sensitive login credentials are then attached to requests sent 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}", ...[truncated 3487 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shopee_top_picks_common.py:217
Finding

Unsanitized Session Identifier Enables Directory Traversal and Out-of-Scope File Writes

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 output path uses the same unsafe 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 even though it comes from the process environment. The code does not reject: - Absolute paths. - `..` traversal components. - Forward or backward path separators. - Symbolic-link traversal. ...[truncated 1792 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shopee_top_picks_common.py:315
Finding

Complete API Responses Are Persisted in Plaintext Without Restrictive Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/_shopee_top_picks_common.py:184
Finding

Output Handling Violates the Declared No-Temporary-Directory Policy

Content
View full analysis
/linkfox///data/-.json` - Writing to `/tmp` is prohibited; report an error if the current directory is not writable. ``` The implementation instead selects the first writable location from the workspace, current directory, home directory, and system temporary directory: ```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 ``` The onboarding implementation uses an equivalent fallback sequence: ```python def _linkfox_root() -> str: global _SESSION_ROOT if _SESSION_ROOT: ...[truncated 1992 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:475
Finding

Generated API Keys Are Exposed Through Standard Output and Persistent Shell Configuration

Content
View full analysis
dict: masked = _mask_phone(phone) if not re.fullmatch(r"\d{11}", phone): return {"error": f"login: 手机号格式不正确: {phone}", "phone": masked} if not re.fullmatch(r"\d{4,8}", code): return {"error": f"login: 验证码格式不正确: {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']}(不影响拿 key)", 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), } ``` The complete object is printed to standard output: ```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} 成功获取 API key(来源: {r['source']})", file=sys.stderr) ...[truncated 2134 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 (32)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The code builds destination URLs from environment-controlled base URLs and then sends login data, access tokens, refresh tokens, and API-token operations to those endpoints via requests.post. If an attacker can influence environment variables in the runtime, they can redirect these sensitive flows to attacker-controlled infrastructure 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
90% confidence
Finding

The gateway URL is also derived from environment variables and used by urlopen together with the Authorization header carrying the API key. A manipulated environment can therefore exfiltrate the API key and route privileged account, package, and order operations to an untrusted endpoint.

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

The description claims a broader skill covering the full Top Picks module with all four API endpoints. The provided code chunk, however, only implements invocation of add_top_picks and contains no evidence of listing, updating, or deleting Top Picks. This is a material description-versus-behavior mismatch for the supplied code chunk. There is no indication of unrelated or suspicious extra behavior; the mismatch is due to overclaiming supported Top Picks capabilities relative to the code shown.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents this skill as a functional Shopee Top Picks API integration module. However, the provided code does not access Shopee, manage Top Picks, call any API, or handle user-triggered Top Picks operations. Its sole purpose is a local dependency check for the presence of linkfox-shopee-store-auth by inspecting environment-derived directories and filesystem paths. While dependency checking could be a supporting component, this code chunk by itself materially differs from the declared primary purpose and implements a separate capability not reflected in the description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description claims the skill covers the entire Shopee Top Picks module with all four APIs and triggers for general Top Picks management. However, the provided code chunk only exposes get_top_picks_list. There is no evidence in this snippet of add, update, or delete behavior. This is a material description-to-behavior mismatch for the supplied code chunk because the declared primary capability is broader than what the code actually does. The code does access the Shopee Top Picks area consistently, so the mismatch is about incomplete represented capabilities rather than unrelated behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says this skill manages Shopee Top Picks collections via Shopee developerProxy and specific Shopee Open API endpoints. However, the supplied code contains no Shopee logic, no /shopee/developerProxy usage, and no Top Picks operations such as get_top_picks_list/add_top_picks/update_top_picks/delete_top_picks. Instead, it interacts with LinkFox login, agent, and payment/account endpoints (api.linkfox.com, agent-api.linkfox.com, tool-gateway.linkfox.com) to onboard users, authenticate by SMS, retrieve API tokens, list plans, place orders, and render payment QR codes. This is a materially different primary purpose and accesses entirely different resources, so the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger conditions are explicitly broad enough to activate even when the user does not clearly mention Top Picks/精选, as long as the request is loosely related to authorized store management. In an agent setting, overbroad activation increases the chance of invoking mutating commerce operations in the wrong context, leading to unintended API calls, data access, or destructive 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 file implements LinkFox onboarding, SMS login, API-key acquisition, package listing, purchasing, and payment QR generation, which is materially unrelated to a Shopee Top Picks management skill. Such capability expansion increases attack surface and can be used to harvest user phone verification codes and provision credentials outside the declared skill purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

Billing and payment-order creation are unrelated to Shopee Top Picks management and let the skill initiate commercial transactions and generate payment artifacts. In the context of a store-management skill, this is dangerous because it creates an unjustified path to charge users or manipulate purchases under the guise of normal API operations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The login and API-token provisioning flow goes beyond the advertised Shopee Top Picks functionality and actively acquires reusable credentials for the broader LinkFox environment. In skill context, this mismatch is especially risky because users may provide SMS codes believing they are authorizing Shopee operations while the code is actually minting platform API keys.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares capabilities that involve environment access, file writes, networking, and shell execution, but it does not define any explicit tool scope such as permissions or allowed-tools. That creates an over-broad execution surface where an agent may use more powerful operations than a user would reasonably expect from a Top Picks management skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill includes state-changing operations such as add, update, and delete, as well as mandatory local persistence of responses, but it does not prominently require informed user confirmation or warn about data-handling consequences. This makes accidental destructive actions and unanticipated local storage of store data more likely in normal use.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs the agent to always write full API responses to local session-scoped files and sometimes print the complete JSON to stdout. Full API payloads can contain store identifiers, operational metadata, and other sensitive business data, so unconditional persistence and output materially increase the risk of exposure through logs, workspace files, or later context reuse.

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 39)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 documentation describes a state-changing POST operation that creates a Top Picks collection in a live Shopee store, but it provides no warning that the action modifies remote merchant data. In an agent setting, this increases the risk of unintended destructive or unauthorized business actions because users may not realize the call is not read-only and an LLM may invoke it without adequate confirmation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This documentation exposes a destructive delete capability for Shopee Top Picks without any cautionary note, confirmation guidance, or mention of irreversibility/scope checks. In an agent skill context, that increases the chance an LLM or user will invoke the delete path casually or through misunderstanding, causing unintended removal of store merchandising data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file's instructional content and field descriptions are written in Chinese, but there is no indication that the skill is region-specific or that users may opt into another language. This creates a natural-language policy concern because the skill effectively imposes a locale/language choice without explicit justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The onboarding flow explicitly instructs collecting a user's phone number to register for an API key, but it provides no privacy notice, consent language, retention guidance, or handling restrictions for this sensitive personal data. In an agent skill context, this can lead to unnecessary collection and exposure of user PII through chat logs, tool outputs, or downstream systems.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill's purpose is to manage Shopee Top Picks through a developer proxy, but this function spawns a separate Python process to run a local dependency checker. Launching subprocesses is a stronger host-level capability than expected for an API wrapper and is not declared in the manifest description.

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_top_picks_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
97% confidence
Finding

The docstring and runtime error message are written only in Chinese, and additional user-facing comments/docstrings later in the file are also Chinese-only. This imposes a locale choice on users without opt-in or documented justification, which matches the language-policy violation criteria.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The helper persistently writes full API responses to local disk and maintains an index/metadata trail, which exceeds the stated purpose of merely forwarding Shopee Top Picks API requests. Those responses may contain shop identifiers, tokens, product metadata, or other sensitive business data, creating unnecessary data retention and local exposure risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Full API responses are saved to disk without clear user-facing disclosure or consent, so sensitive data may be stored in ways users do not expect. Hidden persistence materially increases privacy and data-handling risk, especially for commerce/account-linked API outputs.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Persistently storing complete API responses in plain JSON files can expose sensitive store or user-related data to other local processes, users, backups, or forensic artifacts. In the context of a Shopee store-management skill, this is more dangerous because the data is tied to authorized merchant operations and may include commercially sensitive or account-scoped information.

Content

No source excerpt is available for this finding.