Back to skill

Security audit

Shopee-店铺媒体

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches Shopee media upload, but it also handles login, API keys, billing flows, and persistent sensitive output in ways that need review.

Install only if you trust LinkFox and the environment running the skill. Review or restrict the LINKFOX_* endpoint variables, avoid giving the agent SMS codes unless you intend to use the LinkFox onboarding flow, confirm any paid order before scanning or opening payment links, and treat saved linkfox response files as sensitive because they may contain shop, media, request, or account details.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_shopee_media_common.py:18
Finding

Environment-Controlled Network Endpoints Can Expose Authentication Credentials

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")) ``` The onboarding component applies the same design to account credentials: ```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") ``` ```python def _http_post(url: str, body: dict, headers: dict, timeout: int = 30) -> dict: """General requests POST, returning JSON or {_error, _body}.""" try: _require_requests() exc ...[truncated 2903 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shopee_media_common.py:183
Finding

Unsafe Response Persistence Allows Path Traversal and Undocumented Temporary Storage

Content
View full analysis
str: cached = _LF_SESSION_CACHE.get("_root") if cached: return cached candidates = [] acpx = (os.environ.get("ACPX_WORKSPACES") or "").strip() if acpx: acpx = acpx.split(os.pathsep)[0].strip() if acpx: candidates.append(os.path.join(acpx, "linkfox")) candidates.append(os.path.join(os.getcwd(), "linkfox")) candidates.append(os.path.join(os.path.expanduser("~"), "linkfox")) candidates.append(os.path.join(_lf_tempfile.gettempdir(), "linkfox")) for root in candidates: try: os.makedirs(root, exist_ok=True) probe = os.path.join(root, ".write_probe") with open(probe, "w", encoding="utf-8") as f: f.write("") os.remove(probe) except OSError: continue root = os.path.abspath(root) _LF_SESSION_CACHE["_root"] = root return root fallback = os.path.abspath(candidates[-1]) _LF_SESSION_CACHE["_root"] = fallback return fallback ``` ```python def _lf_session_id(ts: float) -> str: env = os.environ.get("SESSION_ID") if env: return env.strip() if "_auto" not in _LF_SESSION_CACHE: _LF_SESSION_CACHE["_auto"] = ( _lf_time.strftime("%H%M%S", _lf_time.localtime(ts)) + "-" + _lf_secrets.token_hex(3) ) return _LF_SESSION_CACHE["_auto"] ``` ```python def emit_result(result, slug=SLUG, inline=False): """Persist the complete response under linkfox///data/-.json.""" serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = _lf_time.time() date_str = _lf_time.strftime("%Y-%m-%d", _lf_time.localtime(ts)) sid = _lf_session_id(t ...[truncated 2868 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
scripts/onboarding.py:162
Finding

Unpinned Runtime Dependency Installation Creates Supply-Chain Exposure

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 onboarding script instructs users to install `qrcode`, `pillow`, and `requests` directly from the currently configured pip index. The project does not provide exact versions, integrity hashes, a lockfile, or a trusted-index requirement in the reviewed content. Although the named packages are common legitimate dependencies, an unpinned installation resolves to whatever versions the active package index serves at installation time. This makes deployments non-reproducible and increases exposure to compromised package indexes, malicious mirrors, account compromise affecting a future release, or index configuration controlled by an attacker. The Skill does not automatically execute `pip`, so exploitation requires a user or automation system to follow the displayed instruction. ### Attack Path 1. An attacker controls or compromises the pip index configured for the victim environment, such as through `PIP_INDEX_URL`, a pip configuration file, DNS or repository compromise, or a malicious internal mirror. 2. The onboarding command encounters a missing dependency and displays the installation instruction. 3. The victim or surrounding automation runs the suggested unpinned `pip install` command. 4. pip downloads the attacker-selected package distribution. 5. Malicious pa ...[truncated 659 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 (33)

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

Critical
Category
Data Flow
Confidence
95% confidence
Finding

The code constructs outbound requests using a base URL taken from environment variables and sends sensitive headers including the API key and session metadata to that destination. If an attacker can influence LINKFOX_TOOL_GATEWAY or SHOPEE_API_BASE_URL, they can redirect traffic to an attacker-controlled host and exfiltrate credentials and request data.

Content

Scanner excerpt · scripts/_shopee_media_common.py (reported line 88)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 ""

Description-Behavior Mismatch

Critical
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file is not a Shopee media-upload skill at all; it implements an onboarding/login/payment CLI for a different service, including SMS verification, token acquisition, and purchase flows. This severe mismatch strongly suggests deceptive packaging or capability smuggling, which is dangerous because users or orchestrators may invoke it under false assumptions and expose credentials or perform unintended account and billing actions.

Content

No source excerpt is available for this finding.

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

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The code builds destination URLs from environment-controlled base URLs and then sends sensitive authentication material to them via requests.post. Because this script handles SMS login, access tokens, refresh tokens, and generated API keys, a malicious or misconfigured environment can redirect these secrets to an attacker-controlled endpoint, 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
95% confidence
Finding

The gateway request path uses urlopen against a URL derived from environment variables and attaches the API key in the Authorization header. If an attacker can influence LINKFOX_AGENT_API_URL or related variables, all gateway calls, including user info, package, and order operations, can be redirected to an attacker-controlled server that harvests credentials and manipulates 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 or its related flow performs SMS login, API key retrieval, order creation, payment status queries, and QR code generation while claiming to be only a Shopee media proxy, that is a major scope expansion into account and billing functions. Such undocumented account, payment, and credential-handling behavior could expose sensitive identifiers, trigger unauthorized purchases, or mislead users into approving actions unrelated to media upload.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill or its related flow performs SMS login, API key retrieval, order creation, payment status queries, and QR code generation while claiming to be only a Shopee media proxy, that is a major scope expansion into account and billing functions. Such undocumented account, payment, and credential-handling behavior could expose sensitive identifiers, trigger unauthorized purchases, or mislead users into approving actions unrelated to media upload.

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
示 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

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code performs unrelated authentication, token generation, team/account lookup, and order/payment operations that exceed the stated purpose of media upload. In the context of a Shopee upload skill, these extra capabilities are especially dangerous because they enable collection of phone numbers, SMS codes, access tokens, and API keys while also driving purchase flows outside user expectations.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises capabilities that include environment access, file writes, network use, and shell execution, but it does not declare any explicit tool scope or permission boundaries. In an agent setting, this increases the chance of over-broad execution and unintended access to local data or external systems, especially because the skill also documents persistent file writes and script execution.

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-local JSON files, but it does not warn that those responses may include shop identifiers, media URLs, operational metadata, or other potentially sensitive user data. Persisting all responses by default increases the risk of local data leakage, accidental commit to source control, or access by other tools and users on the same system.

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


curl 示例

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

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The onboarding instructions tell the operator to ask users for a phone number and then process SMS-based registration through a script, but they do not include an explicit privacy notice, consent language, or guidance on secure handling of the phone number and verification code. This creates unnecessary privacy and data-handling risk because users may disclose sensitive personal data and OTPs to an agent without understanding retention, visibility, or misuse risks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This function sends query parameters and request bodies to a remote developer proxy, which may include shopId, merchantId, and arbitrary body content. The code performs the transmission without any confirmation prompt, user-facing log/print, or inline warning/comment disclosing that user or system data will be sent externally.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

For a skill whose purpose is Shopee media API upload forwarding, spawning a subprocess to run check_auth_dependency.py is not an obviously necessary capability of the media module itself. This introduces process-execution behavior unrelated to the manifest's declared media API scope.

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_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,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The helper sends an Authorization header built from environment-stored API keys and also includes SESSION_ID, MESSAGE_ID, MODE_ID, and APP_NAME in outbound HTTP requests. Although the module docstring mentions gateway/proxy use, there is no explicit warning, confirmation, or user-facing disclosure here that local environment-derived identifiers and credentials will be transmitted off-host.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The helper persists full API responses and session metadata to local disk under predictable workspace paths, even though the skill's primary role is API proxying for media upload. Those responses may contain tokens, identifiers, upload results, or other sensitive business data, creating unnecessary at-rest exposure to other local processes, users, or later sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The function writes complete serialized API responses to disk and announces the file path, without redaction or sensitivity checks. In this skill context, media API responses and related metadata can include shop identifiers, upload state, or tokens, creating persistent local disclosure risk beyond the user's immediate request.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring and CLI help text are entirely in Chinese, and the workflow hard-codes China-specific assumptions such as domestic phone numbers and +86 area code. There is no natural-language indication that the skill is region-specific or any option for users to choose another language/locale, which can violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/onboarding.py (reported line 196)May include surrounding context.

python
except RuntimeError as e:
        return {"_error": str(e)}
    try:
        r = requests.post(url, json=body or {}, headers=headers, timeout=timeout)
        return r.json()
    except Exception as e:
        body_text = ""

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill’s descriptive and instructional content is overwhelmingly Chinese, including activation guidance and operating instructions, with no indication that users may choose another language. Under the policy, forcing a specific language without opt-in is a natural-language policy issue unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation gives conflicting statements about compute/quota consumption, which can mislead users about the cost and side effects of invoking the skill. While not a direct exploit primitive, inaccurate cost disclosures can cause unexpected charges or coax users into repeated operations they would not otherwise approve.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

L52 says not to implement authorization/token logic inside this skill, but L8 and L12 describe this skill as sending requests through /shopee/developerProxy where the server resolves the token and forwards the request. That is not necessarily a code defect, but the documentation creates an intent contradiction about whether auth handling is part of the skill's effective behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This markdown file contains user-facing instructions primarily in Chinese while also including English content, but it does not state that the skill is intended only for Chinese-speaking users or provide any language-selection option. Under the policy rule for natural-language violations, forcing a specific language or locale without opt-in can be a compliance issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file contains user-facing documentation primarily in Chinese while also embedding English labels such as the purpose and registry notes. For a general skill reference, forcing a specific language or mixed locale without user opt-in can violate language/locale policy requirements.

Content

No source excerpt is available for this finding.