Back to skill

Security audit

Shopee-店铺直播

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches Shopee livestream management, but it also handles account login, API keys, billing orders, payments, and persistent response files with weaker safeguards than users should expect.

Install only if you trust LinkFox to handle your Shopee store operations, phone/SMS onboarding, API keys, and billing flow. Use it from a private workspace, keep the API key out of shared logs and shell history where possible, and require explicit confirmation before deleting items, posting comments, banning users, starting or ending sessions, or creating payment orders.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/_shopee_livestream_common.py:190
Finding

Unvalidated SESSION_ID permits response files to escape the intended storage directory

Content
View full analysis

Vulnerability Details

File Location: scripts/_shopee_livestream_common.py:190-219, 322-330
Vulnerability Type: Path traversal and unsafe temporary-file handling
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
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 = _l
...[truncated 3043 chars]
Remediation
View remediation

Remediation Suggestions

  1. Validate SESSION_ID against a strict identifier allowlist, for example:
    python
    if not re.fullmatch(r"[A-Za-z0-9_-]{1,128}", sid):
        raise ValueError("Invalid SESSION_ID")
    
  2. Reject absolute paths, path separators, . components, and .. components.
  3. Resolve and enforce containment before creating directories:
    python
    root_path = Path(root).resolve()
    session_path = (root_path / date_str / sid).resolve()
    session_path.relative_to(root_path)
    
  4. Remove the shared temporary-directory fallback if /tmp storage is prohibited. Fail closed when approved storage locations are unavailable.
  5. Create response directories and files with restrictive permissions, such as 0700 for directories and 0600 for files.
  6. Use no-follow and exclusive-creation semantics where practical to reduce symlink and race-condition exposure.
  7. Avoid persisting complete responses by default when they can contain sensitive data. Support field filtering, explicit opt-in, and retention controls.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/onboarding.py:487
Finding

Generated API key is exposed through standard output and plaintext shell configuration guidance

Content
View full analysis

Vulnerability Details

File Location: scripts/onboarding.py:487-506 and references/onboarding.md:11-17
Vulnerability Type: Plaintext credential exposure
Risk Level: Medium

Vulnerable Code

python
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),
}
python
def _emit(obj: dict) -> None:
    print(json.dumps(obj, ensure_ascii=False, indent=2))
python
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} Successfully obtained API key (source: {r['source']})", file=sys.stderr)
        return 0
    return 1

The onboarding documentation additionally directs the user or Agent to place the full key into shell commands that append it to .zshrc or .bashrc, or pass it to setx.

Technical Analysis

After successful SMS authentication, login_and_get_key() returns the complete LinkFox API key in a dictionary. _cmd_login() passes that dictionary directly to _emit(), which serializes the full key to standard output.

In an Agent environment, stdout may be retained in conversation transcripts, execution logs, observability platforms, terminal scrollback, CI logs, or orchestration records. The documentation then recommends forwarding the key to the user and embedding it directly in shell commands. This can additionally disclose it through terminal history, command-line telemetry, copied chat content, backups, and plaintext shell initialization files.

The API key is subsequently used as the Authorization value for LinkFox gateway requests. Its exposure can therefore grant access to the victim's LinkFox account capabili ...[truncated 1543 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not print the complete API key to stdout or stderr. Return only a masked identifier or fingerprint.
  2. Store the credential directly in an OS-backed credential manager such as Windows Credential Manager, macOS Keychain, or a Linux secret service.
  3. If file storage is unavoidable, write the key to a dedicated configuration file with 0600 permissions and ensure its parent directory is 0700.
  4. Avoid passing secrets in command-line arguments or commands likely to be retained in shell history.
  5. Provide an interactive setup routine that receives the credential securely and confirms installation without echoing it.
  6. Redact recognized token fields from logs, exceptions, Agent transcripts, and diagnostic output.
  7. Add key revocation and rotation guidance in case onboarding output has already been logged.
  8. Prefer short-lived, narrowly scoped tokens over long-lived account-wide bearer keys where supported.
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 (55)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/_shopee_livestream_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 ""

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

Critical
Category
Data Flow
Confidence
91% confidence
Finding

The script builds request destinations from environment-controlled base URLs and then sends sensitive authentication material, including SMS login data, access tokens, and generated API keys, to those endpoints. If an attacker can influence environment variables, they can redirect traffic to an attacker-controlled server and exfiltrate credentials or payment-related data; this is especially concerning because the script is an onboarding/login flow.

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 request path uses an environment-derived base URL and attaches the LinkFox API key in the Authorization header before calling urlopen. An attacker who can set the environment can redirect these requests to a hostile host and capture API keys, user/order data, or manipulate downstream payment/order operations.

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 Livestream operations such as create_session, start_session, add_item_list, comments, metrics, and image upload via /shopee/developerProxy. However, the provided code does none of that. It parses environment variables, inspects candidate local skill directories, checks for linkfox-shopee-store-auth/SKILL.md, emits status output, and exits with a dependency-specific code. This is materially different from the declared primary purpose. While dependency checking could be a supporting component of a larger skill, this code chunk itself does not match the described livestream functionality and instead implements a separate installation/dependency check behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

There is a clear and material mismatch. The declared description says this skill should interact with Shopee Livestream APIs via /shopee/developerProxy for livestream session creation, session control, item management, comments, metrics, and image upload. However, the supplied code never references Shopee, livestreams, developerProxy, session management, product lists for livestreams, comments, or image upload to Shopee. Instead, it communicates with LinkFox login, agent, and agent-user endpoints to perform onboarding and commercial/account functions: send SMS login codes, authenticate users, fetch or generate API tokens, inspect plans, place orders, generate payment QR codes, and query payment state. This is not a supporting implementation detail for a Shopee Livestream skill; it is an entirely different primary purpose and capability set.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger rule explicitly says the skill should activate even when the user does not mention livestreams, as long as the topic loosely relates to an authorized Shopee store's session, product, or interaction management. Overbroad triggering is dangerous because it can cause the agent to invoke powerful networked/store-management actions in unrelated conversations, increasing the chance of unintended state changes or data access.

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

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This file implements LinkFox account onboarding, SMS login, plan listing, ordering, and payment support, which is materially unrelated to the declared Shopee Livestream API forwarding purpose. Such hidden scope expansion is dangerous because it introduces credential collection and commerce functionality users would not reasonably expect from a Shopee livestream management skill.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code can create commercial orders and render payment QR codes, enabling monetary transactions outside the stated Shopee livestream management scope. In skill context, this mismatch is more dangerous because it can socially engineer users into approving purchases under the guise of a storefront livestream integration.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script performs SMS-based account login and generates API tokens for LinkFox, which is unrelated to Shopee livestream session/item/comment management. This is dangerous because it collects authentication factors and issues credentials, giving the skill the ability to bootstrap access well beyond its advertised scope.

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 involve environment access, filesystem writes, shell execution, network access, and MCP use, but it does not declare any explicit tool scope such as permissions or allowed-tools. That increases the risk of over-privileged execution because reviewers and runtime policy layers cannot easily constrain what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill states that it will always write full API responses into the current working directory under a project-local path, and forbids /tmp fallback. Writing persistent files into the active workspace without prominent user warning can leak sensitive business data into repos or shared directories, pollute local projects, and create unintended persistence of tokens, session data, or customer interaction content.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The document first warns that the tool consumes compute and may hit billing or quota limits, but later states '不消耗算力' ('does not consume compute'). Contradictory cost and billing statements can mislead users into approving actions they would otherwise decline, which is especially risky when the skill may trigger paid API usage or account balance depletion.

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


curl 示例

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

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file documents an action that bans a user from commenting, which can affect user access and moderation state, but it provides no warning, confirmation guidance, or notice about the operational impact. Under the markdown-specific SQP-2 criteria, descriptions of behaviours that may affect user data or system integrity should disclose such effects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation exposes a destructive item-deletion capability for livestream management but does not warn about irreversible or business-impacting consequences, confirmation expectations, or safe-use constraints. In an agent setting, this increases the chance that a user request is translated into a deletion action without adequate user awareness or explicit confirmation, leading to accidental removal of livestream products.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The document exposes a destructive livestream operation ('Remove currently shown item') but does not warn that invoking it changes the live session state immediately. In an agent setting, sparse safety guidance increases the chance the action is triggered from ambiguous user requests or without confirmation, causing unintended removal of products during an active stream.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file uses Chinese throughout headings, field descriptions, and usage notes, which effectively forces a specific language on readers. Under the policy for natural-language violations, this is a locale/language constraint without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This documentation describes an API that posts a livestream comment on behalf of a store, which is a visible external side effect, but it does not warn operators or downstream agents that invoking it will publicly act as the merchant account. In agentic contexts, missing confirmation/warning language increases the risk of unintended spam, reputational harm, or unauthorized communications if the tool is triggered from ambiguous user input.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file describes an upload operation and a forwarded POST request to a remote Shopee API, which can transmit user-provided image data off-system. Under the markdown criteria for SQP-2, the skill description should warn about privacy or data-handling impact, but no such warning is present in the purpose, forwarding note, or usage example.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The onboarding flow instructs users to provide a phone number and verification code to a script-driven registration process, but it gives no privacy notice, data-handling disclosure, retention policy, or trust boundary explanation. This creates a real privacy and security risk because users may expose sensitive personal data and authentication factors without understanding how they are processed or stored.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The stated purpose is to proxy Shopee Livestream and token-related API calls through developerProxy/storeTokens. Invoking a local checker script with subprocess introduces code-execution capability unrelated to livestream business actions and broader than an obvious implementation requirement for an API-forwarding skill.

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

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The get_api_key docstring is written only in Chinese, which imposes a specific language/locale in user-facing guidance without any visible opt-in or alternative. Under the policy, language constraints should either offer user choice or be clearly documented as justified for a region-specific tool.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The helper persists full API responses to local files under a predictable session directory, even though the skill's stated purpose is API forwarding for Shopee livestream operations. Those responses may contain sensitive business data, tokens, comments, media references, or customer-related information, creating unnecessary retention and local disclosure risk.

Content

No source excerpt is available for this finding.