Back to skill

Security audit

Shopee-店铺退货

Security checks for vulnerabilities and agentic risk

Overview

The skill performs Shopee returns work, but it also bundles account login, API-key generation, billing, automatic feedback, and local data retention that need Review before use.

Review carefully before installing. Use only with a LinkFox/Shopee account where you are comfortable sending return, dispute, proof, shop, phone, token, and billing data through LinkFox services. Require explicit human confirmation before confirm, dispute, cancel_dispute, offer, accept_offer, upload_proof, order, or payment actions. Avoid storing API keys permanently in shell profiles unless that is acceptable for the machine, and clean up locally saved response files because they may contain customer or business data.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:135
Finding

Automatic Third-Party Feedback and Promotional Output Hijacking

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/onboarding.py:358
Finding

Returns Skill Implements Excessive Authentication, Token Generation, and Payment Capabilities

Content
View full analysis
dict: resp = _login_post("/user/v3/web/login", { "type": "sms", "method": "login", "systemId": "LinkFoxAgent", "data": {"areaCode": "+86", "authPhone": phone, "authCode": code, "sourceChannel": channel or "skill"}, }) if "_error" in resp: return {"error": f"login: {resp.get('_body') or resp['_error']}"} if not (resp.get("success") or resp.get("code") == "OK"): return {"error": f"login: {resp.get('message') or json.dumps(resp, ensure_ascii=False)}"} data = resp.get("data") or {} access_token, user_id = data.get("accessToken"), data.get("userId") if not access_token or not user_id: return {"error": f"login: Response lacks accessToken/userId: {json.dumps(resp, ensure_ascii=False)}"} return { "access_token": access_token, "refresh_token": data.get("refreshToken", "") or "", "user_id": str(user_id), "nick_name": data.get("userName", ""), "is_new_user": bool(data.get("newUser") or data.get("isFirstRegister")), } ``` It then sends the access token to retrieve team and member information: ```python def _fetch_user_info_v3(access_token: str, user_id: str) -> dict: """Get group_id / member_id from userInfo.""" resp = _http_post(f"{_login_base()}/linkFoxApp/api/userCenter/userInfo", {}, _headers("agent-linkfox-web", "agent.linkfox.com", access_token=access_token, user_id=user_id)) if "_error" in resp: return {"error": f"userInfo: {resp.get(' ...[truncated 4665 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shopee_returns_common.py:177
Finding

Complete Return and Dispute Responses Are Persisted in Plaintext with an Unsafe Temporary-Directory Fallback

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 ``` Every complete response is then serialized and written without explicit owner-only permissions, redaction, or retention controls: ```python def emit_result(result, slug=SLUG, inline=False): """Persist full 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 = _lf_session_id(ts) root = _lf_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_o ...[truncated 3029 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:163
Finding

Runtime Installation Instructions Use Unpinned Third-Party Dependencies

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} ``` ```python def _require_requests() -> None: if requests is None: raise RuntimeError("Missing requests dependency; run: pip install requests") ``` ### Technical Analysis The script directs users to install `qrcode`, `pillow`, and `requests` without version pins, hashes, a lock file, or a constrained package index. Package names are not dynamically derived and there is no evidence that these specific packages are malicious. The risk arises because the installed artifact can change after the Skill has been reviewed, making execution non-reproducible and exposing users to future compromised releases, dependency-chain compromise, or incompatible updates. Python packages and their build backends can execute code during installation, and imported packages execute module initialization code at runtime. Therefore, unconstrained installation expands the effective codebase beyond what was audited. ### Attack Path 1. The user invokes onboarding or payment QR functionality. 2. The script detects that `requests`, `qrcode`, or `Pillow` is absent. 3. The user follows the displayed unconstrained `pip install` instruction. 4. The package manager downloads the latest package and transitive dependencies available at that time. 5. A compromised or unexpectedly changed release executes during installation or import in the user’s Python environment. ### Impact Assessment A compromised dependency would execute with the privileges of the user running `pip` or the Ski ...[truncated 262 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 (44)

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

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The code builds request destinations from environment-controlled base URLs and then sends sensitive onboarding data, including phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys, to those endpoints. If an attacker can influence the environment variables, the skill can be redirected to an attacker-controlled server, causing credential exfiltration and account compromise.

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 path uses a base URL derived from environment variables and sends authenticated requests with the LinkFox API key in the Authorization header. An attacker who can set or poison that environment value can redirect requests to a malicious host and capture API keys, account data, order information, and payment-related responses.

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 flows such as SMS login, token/API-key generation, account retrieval, billing, and payment handling while claiming only returns/refunds functionality, that is a significant trust and scope violation. Such hidden account and payment capabilities expand the attack surface and could expose sensitive identity, authentication, or financial actions under misleading labeling.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill actually includes flows such as SMS login, token/API-key generation, account retrieval, billing, and payment handling while claiming only returns/refunds functionality, that is a significant trust and scope violation. Such hidden account and payment capabilities expand the attack surface and could expose sensitive identity, authentication, or financial actions under misleading labeling.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger condition explicitly says the skill should activate even when the user does not mention returns, as long as the request loosely involves an authorized Shopee shop's return/refund handling. Overly broad activation can cause the wrong skill to run, leading to unintended network calls, data access, or state-changing operations such as confirming returns or opening disputes without sufficiently explicit user intent.

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

This file implements LinkFox account onboarding, SMS login, API-key retrieval, package listing, order creation, and payment QR generation, which is unrelated to a Shopee returns/refunds skill. The mismatch is dangerous because it expands the skill's capabilities into credential handling and billing flows, creating an unexpected path for collecting secrets and initiating paid actions under the guise of unrelated business functionality.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code contains account provisioning and billing functionality, including API token generation and purchase/order flows, that is not justified by the declared Shopee returns/refunds scope. In this context, the extra capability is especially risky because it can induce users or hosts to authenticate, generate long-lived credentials, and perform financial actions unrelated to the advertised skill purpose.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises capabilities that involve environment access, file writes, network access, and shell execution, but it does not declare any explicit tool scope such as permissions or allowed-tools. This weakens least-privilege controls and makes it harder for a host or reviewer to understand or constrain what the skill can do, increasing the risk of unintended data access or command execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill states that full API responses are always written to local disk, potentially including return details, customer data, logistics information, or dispute evidence, but it does not clearly warn the user about local persistence. Silent persistence increases the risk of sensitive e-commerce data being retained in project directories, exposed to other tools, committed to source control, or accessed by other users on the same system.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document states both that the tool consumes credits and that it does not consume credits, which can mislead users into authorizing additional actions under false cost assumptions. While not a direct code-execution flaw, contradictory billing semantics undermine informed consent and can drive unintended paid activity or evasive retry logic.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs automatic feedback reporting, including when the user expresses dissatisfaction or praise, without clearly warning that user interactions may be sent to a feedback API. This creates a privacy and consent problem because conversational content and metadata could be transmitted to a third party unexpectedly.

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 86)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 documentation exposes a state-changing returns action ('accept_offer') and explicitly says to pass the full body, but it does not warn that this operation can finalize or materially alter a live refund/returns dispute outcome. In an agent setting, missing confirmation and consequence warnings increases the chance of unintended approval of buyer/seller offers, causing financial loss, workflow errors, or irreversible case-state changes in authorized stores.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation exposes a workflow-destructive action ('cancel_dispute') but does not warn that invoking it may change dispute state, affect refund/return handling, or be difficult to reverse. In an agent skill, missing cautions and confirmation requirements increase the chance of accidental execution from ambiguous user requests, especially because the skill is designed to trigger broadly on returns/refunds workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation exposes a write action that confirms a return, but it does not warn that this is an operationally significant and potentially irreversible seller action. In an agent-driven environment, ambiguous docs and examples can cause an LLM or user to invoke the endpoint without explicit confirmation, leading to unintended return acceptance, financial loss, and workflow disruption.

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 a state-changing returns dispute action ('Open return dispute; pass full body') without any warning that it can alter a merchant account’s dispute status and affect customer-service outcomes. In an agent-driven context, this increases the chance that an automated workflow or inattentive operator invokes the endpoint as if it were a harmless lookup, causing unintended account-affecting actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation explicitly encourages passing the full request body to a state-changing returns API ('offer') without warning that this action can modify a live refund/return dispute. In an agent setting, this increases the risk of unsafe automation, accidental submission of irreversible seller offers, or user confusion about whether the action is read-only versus transactional.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation explicitly supports uploading return proof and says to pass the full body, but it provides no warning that proof materials may contain sensitive personal or financial data such as names, addresses, phone numbers, parcel labels, or refund evidence. In a returns workflow, this omission increases the chance that an agent or operator will transmit unnecessary or overbroad customer data through the proxy without minimization or consent checks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The onboarding instructions ask users to provide a phone number for script-driven registration, but they do not disclose how that phone number will be handled, stored, transmitted, or retained. In a security-sensitive agent skill, collecting personal data without an explicit privacy notice increases the risk of unintended disclosure, improper handling, or user coercion into sharing sensitive information.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The skill's stated purpose is handling Shopee return/refund operations through store token resolution and developerProxy calls. Spawning a subprocess to run another script is not an obvious requirement of that purpose and introduces an execution capability unrelated to the business function of returns processing itself. This is especially notable because the manifest frames the skill as an API-forwarding integration, not as one that executes local programs.

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_returns_common.py (reported line 37)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,

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The helper persistently writes full API responses and session metadata to local disk under predictable directories, including Shopee returns/refunds data that may contain customer, order, logistics, dispute, or token-adjacent sensitive business information. This behavior is not part of the declared API-forwarding function and creates an undocumented data retention channel that increases exposure to local compromise, accidental disclosure, or later collection by other tools/processes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

emit_result() writes complete API responses to disk and announces only the file path after the fact, with no prior user-facing warning or consent flow. In the context of Shopee returns/refunds operations, these responses can include commercially sensitive and customer-related data, so silent archiving materially raises privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The session-archiving layer stores full API results plus metadata such as session IDs, timestamps, called skills, and file indexes across reusable directories. For a skill handling refunds, disputes, reverse logistics, and store-linked operations, this creates a broad retention and correlation surface that can expose sensitive operational data beyond the immediate request lifecycle.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.