Back to skill

Security audit

a-stock-investment

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed A-share market search helper that uses Tavily as expected, with privacy and financial-reliability cautions but no evidence of hidden or destructive behavior.

Install this only if you are comfortable using a Tavily API key and sending market-search queries to Tavily. Treat the generated market analysis as informational, verify important claims against reliable financial sources, and avoid putting private data, account details, or confidential trading plans into search prompts.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/search-stock.mjs:91
Finding
Untrusted Search Content Is Forwarded to the Agent Without Prompt-Injection Controls<![CDATA[ ## Vulnerability Details **File Location**: `scripts/search-stock.mjs:91-113`; related consumption instructions in `SKILL.md:66-69` **Vulnerability Type**: Indirect prompt injection through untrusted remote search content **Risk Level**: Medium ### Vulnerable Code ```javascript // Print AI-generated answer if available if (data.answer) { console.log("## Answer\n"); console.log(data.answer); console.log("\n---\n"); } // Print results const results = (data.results ?? []).slice(0, n); console.log("## Sources\n"); for (const r of results) { const title = String(r?.title ?? "").trim(); const url = String(r?.url ?? "").trim(); const content = String(r?.content ?? "").trim(); const score = r?.score ? ` (relevance: ${(r.score * 100).toFixed(0)}%)` : ""; if (!title || !url) continue; console.log(`- **${title}**${score}`); console.log(` ${url}`); if (content) { console.log(` ${content.slice(0, 300)}${content.length > 300 ? "..." : ""}`); } console.log(); } ``` The related workflow in `SKILL.md:66-69` directs the agent to consume this output: ```markdown 用户说 "今天A股怎么样" 或 "帮我分析一下股市" 时: 1. 运行搜索脚本获取最新数据 2. 综合分析给出投资建议 ``` ### Technical Analysis The script retrieves an AI-generated answer and search-result fields from Tavily, then writes those fields directly to standard output. The returned `data.answer`, result titles, URLs, and content excerpts originate from external services and indexed websites. They are therefore attacker-influenced data. No trust-boundary marker, output encoding policy, prompt-injection filtering, source allowlist, or instruction hierarchy is applied before this content is exposed to the agent. Meanwhile, the Skill instructs the agent to synthesize the script output into investment analysis. An indexed page can consequently place instruction-like text in its title or content, and Tavily may reproduce that text in `data.answer` or `results[].content`. This does not cause the Node.js script itself to ...[truncated 1923 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Update `SKILL.md` to state explicitly that all search answers, titles, URLs, and excerpts are untrusted evidence and must never override system, developer, user, or Skill instructions. 2. Require the agent to ignore commands, requests, policies, or tool instructions embedded in search results. 3. Return structured JSON rather than instruction-like Markdown. Place remote values only in clearly named data fields such as `source_title`, `source_url`, and `source_excerpt`. 4. Disable `include_answer` by default or avoid forwarding `data.answer`, because it is generated from potentially adversarial source material and can blend source data with instruction-like prose. 5. Validate returned URLs and consider an allowlist of reputable financial and regulatory sources. 6. Require corroboration from multiple independent, trusted sources before producing factual market claims or investment recommendations. 7. Preserve source attribution so the agent and user can distinguish reported facts from generated summaries. 8. Apply output length limits and normalization to every remote field. Filtering alone must not be treated as a complete prompt-injection defense. 9. Ensure the host agent uses least privilege and requires confirmation before consequential tool actions. 10. Add adversarial tests containing instruction-like text in search titles, excerpts, and generated answers to verify that such text remains treated solely as untrusted data. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill declares access to an environment variable and relies on an external networked search API, but it does not define any explicit tool scope such as allowed tools or permissions boundaries. This creates unnecessary ambiguity about what the skill may invoke and increases the risk of over-privileged execution, unexpected tool use, or accidental exposure of sensitive configuration like API-backed capabilities.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger description uses broad phrases like asking about A-share market conditions, trends, or analysis, which can overlap with ordinary financial conversation. Overbroad activation can cause the skill to run in unintended contexts, leading to unnecessary external searches, data leakage through prompts sent to third-party services, or agent behavior that bypasses more appropriate domain routing.

Natural-Language Policy Violations

Medium
Confidence
85% confidence
Finding
The skill description and usage are entirely framed in Chinese for A-share analysis, with no indication that the user can choose output language or that Chinese-only behavior is a documented requirement. This can constitute a language/locale policy issue when a skill implicitly constrains interaction language without opt-in.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The usage example includes vague phrases such as asking how the market is today or asking for stock market analysis, which are common conversational requests and may train or encourage loose activation behavior. In a skill that performs external searches, unintended triggering can leak user context to third-party APIs and expand the skill's operational surface without clear user intent.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The file’s natural-language comments and built-in default queries are exclusively Chinese and specific to A-share markets, effectively constraining the skill to a single language/locale without offering a choice. Under the policy, forcing a specific language or locale without opt-in is a natural-language policy violation.

External Transmission

Medium
Category
Data Exfiltration
Content
include_raw_content: false,
  };

  const resp = await fetch("https://api.tavily.com/search", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
Confidence
86% confidence
Finding
The hardcoded use of the Tavily endpoint establishes a fixed external exfiltration path for query content. In the context of an agent skill, this becomes more dangerous if untrusted user input or hidden system/context data can be incorporated into the query, because those contents would be disclosed to the remote provider.

External Transmission

Medium
Category
Data Exfiltration
Content
include_raw_content: false,
  };

  const resp = await fetch("https://api.tavily.com/search", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
Confidence
86% confidence
Finding
The hardcoded use of the Tavily endpoint establishes a fixed external exfiltration path for query content. In the context of an agent skill, this becomes more dangerous if untrusted user input or hidden system/context data can be incorporated into the query, because those contents would be disclosed to the remote provider.

Static analysis

No suspicious patterns detected.