Back to skill

Security audit

产品标题分析

Security checks for vulnerabilities and agentic risk

Overview

This title-analysis skill is not clearly malicious, but it adds account login, API-key generation, billing, payment-order, and broad local persistence behaviors that need review before installation.

Install only if you intentionally want a LinkFox-backed paid analysis skill and are comfortable sending product/title data and account metadata to that service. Prefer setting API keys through a secure secret manager, avoid agent-handled SMS login when possible, verify no LINKFOX_* endpoint variables point to untrusted hosts, and require explicit approval before any billing or payment-order action.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/title_analyze.py:37
Finding

Environment-Controlled API Destinations Can Receive Credentials and Sensitive Data

Content
View full analysis
str: """Gateway base address: LINKFOX_TOOL_GATEWAY takes priority.""" return (os.environ.get("LINKFOX_TOOL_GATEWAY") or "https://tool-gateway.linkfox.com").rstrip("/") def call_api(params): api_url = get_api_url() api_key = get_api_key() data = json.dumps(params).encode("utf-8") headers = { "Authorization": api_key, "Content-Type": "application/json", "User-Agent": "LinkFox-Skill/2.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", ""), } req = Request( api_url, data=data, headers=headers, method="POST", ) try: with urlopen(req, timeout=150) as response: return json.loads(response.read().decode("utf-8")) ``` The onboarding implementation similarly permits overriding every security-sensitive service: ```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 onboarding requests include: ```python resp = _http_post(f"{_agent_user_base()}/account/loginByToken", { "token": access_token, "refreshToken": refresh_token, "device": {"aid": "3026344186", "did": "", "type": "Windows", ...[truncated 2600 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:477
Finding

Newly Issued API Keys Are Exposed Through Standard Output and Plaintext 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), } ``` ```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) return 0 return 1 ``` The documentation recommends persistent plaintext storage: ```bash setx LINKFOX_AGENT_API_KEY "" echo ...[truncated 1889 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/title_analyze.py:214
Finding

Unvalidated Session Identifiers Permit Path Escape and Sensitive Output May Fall Back to Shared Temporary Storage

Content
View full analysis
str: cached = _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")) import tempfile candidates.append(os.path.join(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) _SESSION_CACHE["_root"] = root return root ``` ```python def _session_id(ts: float) -> str: env = os.environ.get("SESSION_ID") if env: return env.strip() if "_auto" not in _SESSION_CACHE: _SESSION_CACHE["_auto"] = ( time.strftime("%H%M%S", time.localtime(ts)) + "-" + secrets.token_hex(3) ) return _SESSION_CACHE["_auto"] def _ensure_session(ts: float) -> tuple[str, str]: date_str = time.strftime("%Y-%m-%d", time.localtime(ts)) sid = _session_id(ts) root = _linkfox_root() session_dir = os.path.join(root, date_str, sid) os.makedirs(session_dir, exist_ok=True) _ensure_meta(root, session_dir, date_str, sid, ts) return root, session_dir ``` ```python out_path = _resolve_output_path(ts) try: with ...[truncated 2916 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/onboarding.py:164
Finding

Runtime Instructions Install Unpinned Third-Party Dependencies

Content
View full analysis
dict: try: import qrcode except ImportError: err = "缺少 qrcode 依赖,请运行: 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("缺少 requests 依赖,请运行: pip install requests") ``` ### Technical Analysis When dependencies are missing, the script directs users to install `qrcode`, `pillow`, and `requests` without version constraints, hashes, a lockfile, or an approved package-index requirement. Running these commands resolves whatever package version is currently selected by the user's configured Python package indexes. A compromised upstream release, malicious mirror, dependency-confusion setup, or poisoned local package-index configuration can therefore introduce attacker-controlled installation or runtime code. The package names shown are established names rather than apparent typosquats, so this is a supply-chain hardening failure rather than evidence that the Skill intentionally references malicious packages. ### Attack Path 1. The user runs onboarding in an environment where one of the optional packages is absent. 2. The script displays an unpinned `pip install` instruction. 3. The user or agent executes the command using configured package indexes. 4. A compromised release, malicious mirror, or higher-priority untrusted index supplies the resolved artifact. 5. Installation hooks or imported package code execute with the privileges of the Python environment's user. 6. Malicious code can access files, environment variables, and network resources available to that user, including Link ...[truncated 562 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (29)

Description-Behavior Mismatch

Critical
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file's implemented behavior is fundamentally unrelated to the declared skill purpose of product-title analysis: it performs account onboarding, SMS authentication, API-key acquisition, subscription listing, ordering, and payment QR generation. This capability mismatch is highly suspicious because it can trick users or orchestrators into invoking credential and billing workflows under the cover of a harmless analytics skill.

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

The code constructs request destinations from environment-controlled base URLs and then sends sensitive data including phone numbers, SMS codes, access tokens, refresh tokens, and derived API-token requests to those endpoints. If an attacker can influence environment variables such as LINKFOX_LOGIN_API_URL or LINKFOX_AGENT_USER_API_URL, they can redirect authentication traffic and secrets to attacker-controlled infrastructure, making this a practical SSRF/exfiltration vector.

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

The gateway request path uses an environment-derived base URL and attaches the Authorization header containing the API key before calling urlopen. If LINKFOX_AGENT_API_URL or LINKFOX_TOOL_GATEWAY is modified, the tool will transmit the bearer credential and business requests to an arbitrary server, enabling credential theft and misuse of the linked account.

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

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

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The request URL and several outbound headers are derived from environment variables, including a fully overrideable gateway base URL via LINKFOX_TOOL_GATEWAY and session-identifying metadata via SESSION_ID/MESSAGE_ID/MODE_ID/APP_NAME. This creates a real SSRF/exfiltration risk in agent environments, because an attacker who can influence environment configuration can redirect authenticated requests and associated metadata to an untrusted endpoint.

Content

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The manifest describes a product-title analysis skill, but the documented implementation extends into authentication, account inspection, payment/package discovery, order creation, QR-code generation, payment-status polling, and local session/file handling. This is a major description-behavior mismatch that can mislead users into authorizing a data-analysis skill that actually performs account and billing operations against external services.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · SKILL.md (reported line 102)May include surrounding context.

md
| MULTIPLE_RECORDS | Each attribute value becomes its own record (default) | Most analysis -- easier to count, sort, and group |
| COMMA_SEPARATED | Multiple values stay in one record, comma-separated | When you want to see all attributes per ASIN at a glance |

## Display Rules

1. **Present data in tables**: Show extracted attributes and their frequencies in clear, sortable tables
2. **Highlight top keywords**: Call out the most frequent attribute values so patterns are immediately visible

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The markdown mandates writing full responses to disk by default without clearly warning the user that their data will be stored locally. Silent persistence materially increases privacy and confidentiality risk because users may expect analysis output to remain in-session rather than become a retained artifact on the filesystem.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file for a product-title analysis skill contains detailed authentication recovery, account registration, API key setup, and billing/payment instructions that are unrelated to the declared skill purpose. This expands the skill's effective capability into account onboarding and payment handling, creating a path for unnecessary credential collection, secret handling, and social-engineering-style abuse if the agent follows these instructions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation instructs the agent to guide users through phone-based login, code verification, plan selection, and payment ordering despite the skill only being described as title tokenization and keyword analysis. In context, this mismatch is especially dangerous because users invoking a benign analytics skill would not reasonably expect account enrollment or payment flows, increasing the risk of covert data collection and unauthorized transactional behavior.

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

Billing and purchase flows are embedded in a skill that claims to analyze product titles, which creates unjustified authority to spend money or initiate purchases. In this context, the mismatch makes the capability more dangerous because users and calling systems would not reasonably expect payment initiation or QR payment generation from a text-analysis tool.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code performs SMS-based login, token exchange, team selection, and API-key generation, none of which are necessary for title-analysis functionality. In the stated skill context, this is especially dangerous because it can harvest authentication factors and mint reusable API credentials while appearing to perform benign content analysis.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises a narrow title-analysis function but declares no explicit tool/permission scope while its documented behavior relies on environment access, file writes, and network calls. That combination gives the skill broader operational power than users would reasonably expect, increasing the blast radius if the skill is misused or its instructions are repurposed.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest description is primarily in Chinese while embedding English trigger phrases, which imposes a language assumption in natural-language behavior. The file does not state that language is user-selectable or that the locale restriction is intentional and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill states that it automatically aggregates products from prior steps in the current conversation, including paginated queries, without a clear user-facing privacy warning or consent checkpoint. This can cause users to unknowingly submit broader conversation-derived data to the analysis tool than they intended.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs the implementation to persist full API responses to local files by default, even though the stated purpose is transient title analysis. Persistent storage creates unnecessary retention of potentially sensitive commercial data, query context, and derived analytics, which can later be accessed by other processes, users, or tools in the workspace.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Mandatory session-scoped logging of full tool responses under the working directory creates durable artifacts that may contain user-derived inputs, product intelligence, and account-linked metadata. In shared or long-lived workspaces, those files can be discovered or reused outside the original interaction context, expanding exposure well beyond the immediate task.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation instructs callers to send an API key in the Authorization header to an external Linkfox endpoint, but it does not warn that user/product data and credentials are being transmitted to a third-party service. In an agent-skill context, this omission can cause downstream systems or operators to forward sensitive marketplace data externally without informed consent or appropriate handling controls.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The curl example demonstrates direct transmission of request content and an authorization secret to a remote external endpoint. While examples are normal in API docs, this still represents a real exfiltration pathway in a skill ecosystem because agents may copy the example mechanically and send user-supplied product datasets or prior conversation data to a third party without meaningful warning.

Content

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

}

text

## curl 示例

```bash
curl -X POST https://tool-gateway.linkfox.com/product/titleAnalyze \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs collecting a user's phone number and handling SMS verification for registration/login, but provides no privacy notice, data minimization guidance, retention limits, or warning about sensitive information handling. This creates unnecessary exposure of personal data and authentication factors, and could normalize asking users for credentials in a context unrelated to the skill's stated function.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The module docstring and command help text are presented in Chinese, which imposes a specific language on users without any visible opt-in or alternative locale support. Under the language/locale policy, forcing a language without user choice is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file creates writable directories under workspace/home/temp and saves QR code PNG files for payments. Persisting payment artifacts to disk is unrelated to tokenizing or statistically analyzing product titles.

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 = ""

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The CLI emits the newly obtained API key directly to stdout in JSON, which can leak secrets into terminal scrollback, logs, CI captures, chat transcripts, or calling-agent telemetry. Because this skill already performs unexpected credential issuance, exposing the token through normal output materially increases the chance of accidental compromise.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The docstring says output is always written under the current working directory and forbids /tmp, but the actual implementation falls back to home-directory and temporary-directory storage. This mismatch can mislead users and reviewers about where sensitive data is persisted, undermining trust and causing unintended data exposure on shared systems.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.