Back to skill

Security audit

Shopee-店铺媒体空间

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly performs the advertised Shopee media upload work, but it also has silent feedback reporting, risky credential handling, and broad persistence/network behaviors that require review before installation.

Review before installing. Only use this skill if you trust LinkFox endpoints and are comfortable sending selected local media, shop identifiers, API responses, phone/SMS onboarding data, and API keys through this package. Avoid custom gateway environment variables unless you fully trust the destination, do not store API keys in shell startup files if possible, and delete saved response files that may contain sensitive shop or media data.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:115
Finding

Automatic Silent Disclosure of User-Derived Feedback to an External Service

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_shopee_media_space_common.py:257
Finding

Unvalidated Session Identifier Enables Response Writes Outside the Intended Directory

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")) ``` ```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): serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = _lf_time.time() date_str = _lf_time.strftime("%Y-%m-%d", _lf_time.localtime(ts)) sid = _lf_session_id(ts) root = _lf_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _lf_ensure_meta(root, session_dir, date_str, sid, ts) data_dir = os.path.join(session_dir, "data") os.makedirs(data_dir, exist_ok=True) out = os.path.join(data_dir, f"{slug}-{int(ts * 1_000_000)}.json") try: with open(out, "w", encoding="utf-8") as f: f.write(serialized) print(f"Saved full response: {out} ({len(serialized)} bytes)") except OSError as e: print(f"Failed to save to {out} ...[truncated 2664 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_shopee_media_space_common.py:20
Finding

Environment-Controlled Gateway Can Receive API Credentials and Local Image Contents

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", "SESSION_ID": os.environ.get("SESSION_ID", ""), "MESSAGE_ID": os.environ.get("MESSAGE_ID", ""), "MODE_ID": os.environ.get("MODE_ID", ""), "APP_NAME": os.environ.get("APP_NAME", ""), }, method="POST", ) try: with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` ```python payload = { "shopId": shop_id, "fileBase64": base64.b64encode(file_path.read_bytes()).decode("ascii"), "fileName": file_path.name, "contentType": content_type, } return call_api(UPLOAD_IMAGE_ENDPOINT, payload) ``` ### Technical Analysis The gateway base URL is accepted from environment variables without validating the URL scheme or hostname. The same destination receives: - The LinkFox API key in the `Authorization` header. - Session and application metadata. - Shop identifiers. - Request bodies. - Complete Base64-encoded local image contents. Base64 is only an encoding and provid ...[truncated 1804 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:484
Finding

Generated API Key Is Printed in Plaintext and Recommended for Plaintext Shell Persistence

Content
View full analysis
None: print(json.dumps(obj, ensure_ascii=False, indent=2)) ``` The onboarding documentation recommends commands equivalent to: ```bash setx LINKFOX_AGENT_API_KEY "" echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc ``` ### Technical Analysis The login workflow returns the complete generated API key in a dictionary, and `_emit` serializes the dictionary directly to stdout. In Agent and automation environments, stdout is commonly retained in transcripts, command logs, CI logs, terminal capture, or tool execution records. The documentation then recommends inserting the full key into shell commands and storing it in plaintext shell startup files. This creates additional exposure through: - Agent conversation history. - Shell history. - Process command capture. - Terminal logging. - Backups and synchronization of shell configuration files. - Other processes or users able to read the configuration. The phone number is masked, but the more sensitive API credential is not redacted. The workflow therefore lacks appropriate secret-handling boundaries. ### Attack Path 1. A user provides a phone number and SMS code for onboarding. 2. The script authenticates ...[truncated 959 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (38)

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

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The code constructs outbound requests using environment-derived configuration, including the base URL and multiple metadata headers, then sends them via urlopen. If an attacker can influence LINKFOX_TOOL_GATEWAY/SHOPEE_API_BASE_URL or the session-related environment variables, they can redirect sensitive API payloads, API keys, uploaded media, and session metadata to an arbitrary endpoint, creating a clear exfiltration channel.

Content

Scanner excerpt · scripts/_shopee_media_space_common.py (reported line 91)May include surrounding context.

python
method="POST",
    )
    try:
        with urlopen(req, timeout=150) as response:
            return json.loads(response.read().decode("utf-8"))
    except HTTPError as e:
        body = e.read().decode("utf-8") if e.fp else ""

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The code builds destination URLs from environment-controlled base URLs and then sends sensitive data to them via requests.post. Because this file handles phone numbers, SMS codes, access tokens, refresh tokens, and API keys, a modified environment can silently redirect authentication traffic to an attacker-controlled endpoint and exfiltrate credentials.

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

The gateway request path uses a URL derived from environment variables and attaches the Authorization API key header before calling urlopen. If an attacker can influence the process environment, they can redirect these requests to an external server and capture the API key or manipulate downstream billing/order actions.

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

The declared description says this skill handles Shopee MediaSpace media uploads and API forwarding. The supplied code does none of that. It is solely a local dependency checker for linkfox-shopee-store-auth, inspecting environment variables, candidate skill directories, and filesystem paths for SKILL.md, then emitting status and exiting. This is a materially different primary purpose from the declared Shopee media-upload functionality, so it is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is specifically about Shopee MediaSpace media upload and proxying Shopee developer API endpoints. The supplied code does none of that: it contains no Shopee endpoints, no media upload logic, no image/video handling, no chunked upload behavior, and no MediaSpace API forwarding. Instead, it is a standalone LinkFox account/environment onboarding and commerce CLI for authentication, package purchase, payment QR rendering, and order lookup. This is a clear primary-purpose mismatch with multiple undeclared capabilities unrelated to Shopee media upload.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
- **Base URL**:`https://tool-gateway.linkfox.com`
- **Method**:POST(网关),上游 Method 见各接口
- **Auth**:Header `Authorization: <api_key>`(`LINKFOXAGENT_API_KEY`)(如未配置 按 SKILL.md 的 **## 解决认证和算力问题** 处理)
- **流程**:授权选店后,图片调用 `/shopee/uploadMediaSpaceImage`;其余接口调用 `/shopee/developerProxy`。业务脚本不读取或传递 access token
- **图片上传**:`POST /shopee/uploadMediaSpaceImage`,传 `shopId`、`filePath`(脚本侧)
- **其余 API path**:经 developerProxy,须 `api/v2/media_space/...`
- **标识**:通常传 **`shopId`**

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
示 JSON 里的 phone/agreements
   - 收到验证码后:`python scripts/onboarding.py login <phone> <code>`
   - 拿到 `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 skill is declared as a Shopee MediaSpace upload capability, but the file implements a separate LinkFox onboarding, login, API-key issuance, package listing, and payment workflow. That mismatch is dangerous because users or orchestrators may grant or invoke the skill for media-upload tasks while it actually performs credential collection and account monetization actions outside the stated scope.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file contains order creation, package retrieval, and payment QR generation logic that is unrelated to Shopee media uploads. In the context of a media-upload skill, hidden billing capabilities materially increase the chance of unauthorized purchases, social engineering, or misuse of stored API credentials.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script performs SMS-based login, refresh/access token handling, group lookup, and API token generation, all of which exceed the declared Shopee media-upload purpose. In a mismatched skill, collecting authentication factors and minting API keys creates a substantial credential theft and account takeover risk if the skill is invoked under false expectations.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill advertises shell, network, environment, and file read/write capabilities but declares no explicit tool scope or permission boundaries. In an agent setting, missing scope declarations increase the chance of over-privileged execution, making it easier for the skill to access local files, secrets, or external endpoints beyond what is necessary for Shopee media upload tasks.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger conditions include broad terms like Shopee upload, media_space, image ID/URL, and video upload references, which can cause the skill to activate in contexts broader than intended. Over-broad invocation raises the risk of unintended network calls, file handling, and persistence of sensitive media-related data when the user did not explicitly request this skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill states that full API responses are always written to project files, potentially including image/video metadata, identifiers, shop information, and other sensitive operational data, without a clear consent or privacy warning. Automatic persistence expands the exposure window for sensitive data and may leak information into repositories, shared workspaces, backups, or later agent context.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The document says the tool consumes compute and may hit quota/balance errors, but later states '不消耗算力' ('does not consume compute'). This contradiction can mislead users or higher-level agents into making repeated calls under false assumptions about cost, potentially causing unexpected charges, throttling, or operational disruption.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

At L13, the documentation explicitly states that business scripts do not read or pass an access token. However, the example request at L73-L81 includes an "accessToken" field in the JSON payload, which directly contradicts that claim and could mislead developers about the intended authentication model.

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


curl 示例

bash
export KEY=$LINKFOX_AGENT_API_KEY

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation explicitly instructs users to read a local image file and send it to a remote API, but it does not clearly warn that local file contents will be uploaded off-device to LinkFox/Shopee infrastructure. This creates a real privacy and data-handling risk because users may accidentally transmit sensitive local files if they misunderstand the operation or provide the wrong path.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The instructions direct the operator to collect a user's phone number and drive a registration/login flow through a local script, but provide no privacy notice, consent guidance, retention limits, or handling safeguards for that personal data. In a support/onboarding context this creates a real risk of unnecessary collection or improper exposure of phone numbers and SMS-based authentication data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill's stated purpose is Shopee media upload and API proxying, but ensure_auth_skill_available spawns a separate Python process to run check_auth_dependency.py. Launching subprocesses is a distinct capability from media handling or API forwarding 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_media_space_common.py (reported line 40)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,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function reads a local file, base64-encodes its contents, and sends it to a remote upload endpoint. While the operation is inherent to an image-upload helper, this file provides no explicit user-facing warning, confirmation, or explanatory comment near the transmission of local file data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The developer proxy can forward arbitrary Shopee API paths, request bodies, and environment-derived session metadata to a remote gateway. In context, this is intended functionality, but it is still dangerous because the proxy is broad and can transmit sensitive business data or tokens without narrowing scope to only the MediaSpace operations described by the skill.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The result-emission layer writes full API responses, session identifiers, skill usage, and file metadata to local disk under predictable directories. Because this skill handles store tokens, developer-proxy results, and uploaded media metadata, persisted artifacts may contain sensitive commercial or authentication-related data that outlives the user session and can be accessed by other local processes or users.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The helper persists full responses and metadata to disk, creating a durable data-retention channel independent of the user-visible output. In a skill that brokers store credentials, media uploads, and arbitrary developer-proxy responses, this materially increases the risk of leakage of tokens, shop data, operational history, or sensitive API content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file contains natural-language strings in Chinese for the top-level description and the missing-dependency reason, with no indication that the skill is intentionally region-specific or that users can opt into a preferred language. This can violate language/locale policy when a skill imposes one language by default.

Content

No source excerpt is available for this finding.