Back to skill

Security audit

谷歌趋势-关键词趋势

Security checks for vulnerabilities and agentic risk

Overview

This Google Trends skill is not clearly malicious, but it needs Review because it handles login, payments, API keys, telemetry, and local persistence with weak scoping and consent.

Review this carefully before installing. Only use it if you trust LinkFox with your search queries, account identifiers, phone-based login flow, and payment actions. Avoid endpoint override environment variables, do not place API keys in shell startup files, and treat feedback reporting and saved local response files as data disclosure/persistence risks.

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

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:147
Finding

Automatic Disclosure of Conversation-Derived Feedback Without Explicit Consent

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/google_trends_keyword.py:60
Finding

Unnecessary Transmission of Agent Session and Message Metadata

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:68
Finding

Credential-Bearing Requests Can Be Redirected to Arbitrary Environment-Configured Hosts

Content
View full analysis
str: for n in (name, *fallbacks): v = os.environ.get(n) if v: return v.rstrip("/") return default.rstrip("/") 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 headers are then attached without destination validation: ```python def _http_post(url: str, body: dict, headers: dict, timeout: int = 30) -> dict: try: _require_requests() except RuntimeError as e: return {"_error": str(e)} try: r = requests.post(url, json=body or {}, headers=headers, timeout=timeout) return r.json() ``` ```python if access_token: h["authorization"] = access_token h["uid"] = _uid_header(access_token, user_id) if user_id else _LOGIN_FIXED_UID ``` ### Technical Analysis The login API, agent-user API, and gateway base URLs can all be replaced through environment variables. The implementation does not enforce HTTPS, validate certificates beyond library defaults, or restrict destination hostnames to trusted LinkFox domains. After resolving these configurable bases, the script transmits sensitive data including: - Phone numbers and SMS verification codes. - Access and refresh tokens. - API keys. - User and group identifiers. - Payment and order information. An attacker who can influence the execution environment does not need to modify the Skill files. They can redirect credential-bear ...[truncated 1367 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/onboarding.py:484
Finding

API Key Is Printed to Standard Output and Recommended for Plaintext Persistent Storage

Content
View full analysis
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) ``` The documentation recommends permanent plaintext shell configuration: ```bash echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.zshrc && source ~/.zshrc echo 'export LINKFOX_AGENT_API_KEY=""' >> ~/.bashrc && source ~/.bashrc ``` ### Technical Analysis The successful login result contains the complete API key, and `_emit()` serializes that result directly to standard output. Standard output may be retained by agent transcripts, terminal scrollback, CI logs, shell wrappers, or monitoring systems. The onboarding instructions then recommend appending the key to shell startup files. These files are long-lived plaintext storage and are inherited by every process launched from the shell. Their contents may also enter backups, support bundles, or dotfile repositories. The implementation does not mask the key, use a secure credential store, enforce restrictive permissions, or describe revocation and rotation. ### Attack Path 1. The user runs `python scripts/onboarding.py login `. 2. The script generates or retrieves an API key. 3. The complet ...[truncated 751 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/onboarding.py:162
Finding

Unpinned Runtime Dependency Installation Instructions

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 pinned versions, hashes, a lock file, an isolated environment, or a specified trusted package index. Package installation executes package build and installation logic with the privileges of the invoking user. The effective code may change over time even when the audited Skill package remains unchanged. No evidence of a deliberately malicious package name or unsafe custom package index was found. The issue is the uncontrolled supply-chain exposure created by unpinned installation instructions. ### Attack Path 1. The user invokes a code path requiring `requests`, `qrcode`, or Pillow. 2. The dependency is absent. 3. The script instructs the user to run an unpinned `pip install` command. 4. Pip resolves the latest available package and transitive dependency versions from its configured index. 5. A compromised package release, compromised index, or malicious dependency update executes during installation or import. 6. The dependency code runs with the user's local privileges. ### Impact Assessment A compromised dependency could execute arbitrary code with the invoking user's permissions, access environment variables such as the LinkFox API key, read local files, alter Skill ...[truncated 200 chars]
Remediation
View remediation
` commands as the primary remediation. - Integrate dependency vulnerability and update monitoring into release procedures. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/google_trends_keyword.py:203
Finding

Undocumented Fallback Persists Complete Responses in Home or Temporary Directories

Content
View full analysis
str: """选择可写的 linkfox 根目录。 优先级: 1. $ACPX_WORKSPACES 第一个路径下的 linkfox/(真实的工作目录) 2. 当前工作目录下的 linkfox/ 3. ~/linkfox/ 4. $TMPDIR/linkfox/ 当某路径只读(如 cwd 为 /tmp 或只读目录)时,自动回退到后序选项。 选定结果在进程内缓存,保证同一次运行内所有落盘路径稳定一致。 """ 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 ``` Complete results are subsequently written: ```python serialized = json.dumps(result, ensure_ascii=False, indent=2) ts = int(time.time()) out_path = _resolve_output_path(ts) try: with open(out_path, "w") as f: f.write(serialized) ``` ### Technical Analysis `SKILL.md` states that complete responses are written under the current working directory, that writing to `/tmp` is prohibited, and that an unwritable current directory should cause an error. The implementation instead falls back to the user's home directory and then to t ...[truncated 1479 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
Findings (25)

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 request sent to the remote gateway includes multiple environment-derived headers, and the destination base URL is itself overrideable via the LINKFOX_TOOL_GATEWAY environment variable. In an agent/runtime environment, this allows untrusted or attacker-influenced environment data such as SESSION_ID, MESSAGE_ID, APP_NAME, and especially the API key to be transmitted to an arbitrary endpoint, creating a realistic SSRF-plus-secret-exfiltration risk.

Content

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

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 outbound request URLs from environment-controlled base URLs and then sends sensitive data, including phone numbers, SMS codes, access tokens, refresh tokens, and generated API keys, to those destinations. If an attacker can influence the environment, they can redirect authentication and token traffic to an attacker-controlled host, 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
96% confidence
Finding

The gateway request path uses an environment-derived base URL and attaches the API key in the Authorization header before calling urlopen. An attacker who can control the environment can redirect these authenticated requests to a malicious server and harvest API keys or manipulate order, account, and billing 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 purpose is Google Trends analysis, but the documented behavior includes authentication, API key retrieval, account/package/team/order/payment APIs, SMS login, and local storage of session/payment artifacts. This is a serious scope expansion that can expose identity, billing, and credential material under the cover of an analytics skill, violating least privilege and user expectation.

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

text
Track the rise of "AI glasses" search interest over the past two years in the US.

## Display Rules

1. **Present data clearly**: Show trend data in well-formatted tables or describe the trend curve. Include key data points such as peak values, troughs, and notable changes.
2. **Explain the scale**: Remind users that Google Trends values are on a 0-100 normalized scale, where 100 = peak popularity in the selected scope.

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

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module documentation promises that /tmp must not be used and that an unwritable current directory should cause an error, but the implementation silently falls back to home and temporary directories. This discrepancy can cause sensitive outputs to be written into less controlled locations, undermining operator expectations and potentially exposing data to other local users or cleanup mechanisms.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file implements LinkFox onboarding, SMS login, API key retrieval, package listing, and payment operations, which are unrelated to the declared Google Trends keyword analysis purpose. This severe capability mismatch indicates deceptive functionality that can trick users into disclosing phone numbers, verification codes, and payment actions under false pretenses.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill contains package enumeration, order creation, and payment QR generation even though its stated purpose is Google Trends analysis. In this context, commercial purchase capabilities are unjustified and can facilitate unauthorized charges, phishing-like monetization flows, or coercive upsell behavior unrelated to user intent.

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 verification, account login, token exchange, team discovery, and API token generation despite the skill claiming to analyze search trends. This mismatch is especially dangerous because it collects authentication factors and issues reusable credentials, enabling account takeover or persistent unauthorized API access.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill instructs use of environment variables, local file writes, and network/API access, but declares no explicit tool scope or permissions boundary. That creates an authorization ambiguity where a trend-analysis skill can exercise broader capabilities than users or orchestrators may expect, increasing the chance of unintended data access or side effects.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger conditions are broad enough to activate on generic market or trend-analysis requests even when the user did not intend to use Google Trends. Overbroad triggering can cause unnecessary external calls, charges, and data handling in contexts where a simpler or safer response would suffice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The instruction says keywords 'must' be in the target country's language and directs the agent to translate user-provided keywords before querying. This imposes a language/locale behavior automatically rather than offering the user a choice or confirming that translation is desired.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill directs automatic feedback reporting to a separate API whenever certain conditions apply, without presenting it as an explicit optional action. That creates an undisclosed secondary data flow beyond the stated trend-analysis purpose, potentially sending user interaction content or metadata to another service without clear consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Line L15 states that keywords 'must' be in the country's language and instructs translation if they are not. This imposes a language/locale requirement in the skill documentation without presenting it as optional or giving the user a choice, which matches the language/locale policy violation criteria.

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

}

text

## curl 示例

```bash
curl -X POST https://tool-gateway.linkfox.com/googleTrend/getTrendByKeys \

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file documents a second API endpoint for submitting feedback that is unrelated to the stated Google Trends retrieval function. In an agent-skill context, this broadens the skill’s effective capability from read-only data retrieval to outbound content transmission, which can be abused to exfiltrate user content or create unauthorized side effects if an agent follows the embedded documentation blindly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The onboarding flow explicitly instructs the operator to collect and pass a user's phone number into a local script-based registration process, but provides no privacy notice, consent guidance, retention limits, or handling safeguards for this personal data. In an agent skill context, this increases the risk of unnecessary collection, logging, disclosure, or misuse of sensitive user information during support flows.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The inline comment at SMALL_THRESHOLD states that responses below the threshold are output directly and not saved, but main() always resolves an output path and writes the serialized response before deciding whether to print the full JSON or only a summary. This is a direct contradiction between the code comment and actual behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script stores full API responses, cache entries, and per-session metadata locally even though the skill's stated purpose is just trend retrieval/analysis. Persisting complete responses and session linkage data increases exposure of potentially sensitive query content, results, and user/workflow metadata beyond what is needed for immediate execution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language help text is entirely in Chinese, and the login/send-code flows are constrained to 11-digit domestic phone numbers with area code +86. This enforces a specific language and locale behavior without presenting an opt-in, alternative locale, or explicit justification that the skill is intended only for a China-specific audience.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill creates session directories and saves payment QR PNG files under a local linkfox path, which is a file-write operation affecting the user's filesystem. While the top-level docstring mentions QR rendering, it does not clearly warn users that a PNG file will be persisted to disk and where it may be stored.

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

The skill returns a generated API key directly in stdout JSON without any in-file safeguards, masking, or strong warning about secret handling. In agent and CLI environments, stdout is often logged, persisted, or shown to intermediaries, so exposing long-lived credentials this way materially increases secret leakage risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file contains user-facing usage and behavior documentation in Chinese, including key operational details about output handling, but does not offer an alternate language or ask for user opt-in. Under the policy rule, forcing a specific language without choice is a natural-language locale violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.