Back to skill

Security audit

Stockselectionmodel.Bak

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stock-research purpose, but it adds undisclosed branding and directly renders untrusted news links in financial reports.

Review before installing. Use it only if you are comfortable with outbound stock/news queries, optional Tavily API use, Chinese China-market output, local JSON files being left under .local, and hardcoded Content Science branding in reports. Treat generated stock content as informational only and be cautious with rendered links from news sources.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • 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
  • 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)

T01 · Skill Instruction Hijacking

Error
Location
scripts/generate_brief.js:133
Finding

Undisclosed branding is forcibly injected into all generated reports

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_brief.js:133, scripts/generate_brief.js:287, scripts/generate_brief.js:296, scripts/generate_brief.js:305, scripts/generate_brief.js:314, and scripts/generate_brief.js:322
Vulnerability Type: Persistent output manipulation
Risk Level: High

Vulnerable Code

javascript
L.push(`内容科学|Content Science`);
javascript
L.push(`— 内容科学|Content Science · 以上内容由 AI 基于公开数据生成,仅供参考,不构成投资建议 —`);
javascript
L.push('内容科学|Content Science');
javascript
L.push('— 内容科学|Content Science · 仅供参考,不构成投资建议 —');
javascript
L.push('内容科学|Content Science');
javascript
L.push('— 内容科学|Content Science · 仅供参考,不构成投资建议 —');

Technical Analysis

The report generator unconditionally inserts the “Content Science” attribution at the beginning and end of sector, AI-news, and monitoring reports. This attribution is not disclosed as a required component of the fixed report layout in SKILL.md.

Because the Skill instructs the agent to send generated Markdown directly to the user, these statements systematically alter agent-facing output with author-selected promotional attribution. The user cannot disable the attribution through the documented command-line options.

This is classified as instruction hijacking because the executable behavior modifies the intended response format with undeclared content whenever the Skill workflow is followed. It does not modify system safety controls or grant operating-system privileges, but it compromises response integrity and attribution.

Attack Path

  1. A user requests a sector report, AI-news brief, or market-monitoring report.
  2. The agent follows the workflow in SKILL.md and executes scripts/generate_brief.js.
  3. The selected Markdown builder unconditionally inserts the hardcoded branding.
  4. The workflow directs the agent to send the generated Markdown directly to ...[truncated 684 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove all unconditional “Content Science” header and footer statements from the Markdown builders.
  2. Keep the output aligned with the report layout documented in SKILL.md.
  3. If attribution is legitimately required, disclose it clearly in SKILL.md.
  4. Make attribution opt-in through an explicit option such as --include-attribution.
  5. Keep attribution disabled by default and honor requests for unbranded output.
  6. Add snapshot tests that compare generated output against the documented layout and fail when undeclared content is inserted.
  7. Review future output-template changes to ensure they do not introduce promotional links, calls to action, or misleading sponsorship claims.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_brief.js:162
Finding

Untrusted news metadata is rendered as Markdown without sufficient escaping or URL validation

Content
View full analysis

Vulnerability Details

File Location: scripts/fetch_sector_news.js:61-67, scripts/fetch_us_related.js:123-130, scripts/generate_brief.js:162-165, and scripts/generate_brief.js:267-270
Vulnerability Type: Markdown content injection and unsafe link rendering
Risk Level: Medium

Vulnerable Code

scripts/fetch_sector_news.js accepts remote fields with only HTML stripping:

javascript
const items = list.map(x => ({
  title: stripHtml(x.title),
  summary: truncate(stripHtml(x.content), 60),
  source: x.mediaName || '',
  time: x.date || '',
  url: x.url || '',
}));

scripts/fetch_us_related.js performs equivalent processing:

javascript
for (const x of list) {
  allEvents.push({
    title: stripHtml(x.title),
    summary: truncate(stripHtml(x.content), 80),
    source: x.mediaName || '',
    time: x.date || '',
    url: x.url || '',
  });
}

The report generator replaces table separators but does not escape other Markdown syntax or validate link schemes:

javascript
const summary = (n.summary || n.title || '').replace(/\|/g, '|');
const source = (n.source || '').replace(/\|/g, '|');
const link = n.url ? `[查看](${n.url})` : '-';
L.push(`| ${summary} | ${timeShort} | ${source} | ${link} |`);

The same issue affects event output:

javascript
const summary = (e.summary || e.title || '').replace(/\|/g, '|');
const source = (e.source || '').replace(/\|/g, '|');
const link = e.url ? `[详情](${e.url})` : '-';
L.push(`| ${summary} | ${timeShort} | ${source} | ${link} |`);

Technical Analysis

News titles, summaries, source labels, and URLs originate from an external Eastmoney response. The fetch scripts remove HTML tags, but HTML stripping does not neutralize Markdown control characters.

The generator only replaces pipe characters. It does not escape brackets, parentheses, backticks, backslashes, newlines, or other characters capable ...[truncated 1957 chars]

Remediation
View remediation

Remediation Suggestions

  1. Treat every field returned by external services as untrusted.
  2. Implement a dedicated Markdown-escaping function for titles, summaries, and source labels. Escape backslashes, backticks, brackets, parentheses, emphasis characters, angle brackets, and line breaks.
  3. Remove or normalize control characters before generating Markdown tables.
  4. Parse every remote URL with the standard URL class before rendering it.
  5. Permit only the https: scheme and reject credentials embedded in URLs.
  6. Apply an allowlist for expected news domains when practical.
  7. If validation fails, render the URL as plain text or omit the link rather than interpolating it into Markdown.
  8. Consider displaying the normalized hostname next to each link so users can verify its destination.
  9. Add tests containing malicious Markdown payloads, embedded newlines, malformed URLs, encoded schemes, and deceptive link destinations.
  10. Where platform support permits, construct messages using structured components instead of concatenating raw Markdown.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description promises an analysis-oriented skill for A-share sectors, including mapping global news to A-shares, evaluating sector trends, linking U.S. market impacts, classifying positive/negative developments, and reminding about major events. The supplied code only collects AI-related news via Tavily or direct scraping from a fixed set of mostly English-language AI/tech news pages, then deduplicates, scores by AI keywords, and emits structured JSON. While the code may be a supporting news-ingestion component, the actual code chunk itself does not implement the core declared behaviors. This is a material description-behavior mismatch because the primary purpose in code is news retrieval/filtering, not the claimed investment research and market analysis functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code's actual behavior is limited to fetching and lightly processing sector-related news from Eastmoney search results. It does not implement the analytical or cross-market capabilities promised in the description, such as mapping global news to A-share sectors, trend assessment, U.S. stock linkage analysis, sentiment/impact evaluation, or event reminders. It also does not provide multi-platform formatted output beyond raw JSON. While the general topic of sector news is related, the primary purpose described is much broader and more analytical than the supplied code actually performs.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

该脚本的实际功能较窄:基于静态 sector→美股映射表,抓取东方财富搜索结果中的相关文章,经过简单正则过滤后输出 us_stocks 和 events。它确实部分覆盖了宣称中的“美股关联”和“大事件提醒”,但没有看到任何趋势判断、情绪/利好利空归类、A股板块分析逻辑,亦无多平台渲染适配代码。因此描述明显夸大了能力,属于描述与行为不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description promises a fairly comprehensive A-share real-time research tool, including global-news-to-A-share mapping, sector trend judgment, U.S. stock linkage, positive/negative impact analysis, major event alerts, and formatting compatibility for several platforms. The supplied code implements only a narrow subset: it reads keywords or article text, performs substring matching against a predefined mapping table, deduplicates matched A-share entries, sorts by sector, and emits JSON. While this partially aligns with the 'global news → A-share mapping' portion, it lacks the other core promised behaviors and therefore the description materially overstates the skill’s functionality.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a broader market intelligence/research tool centered on global news mapping to A-shares, sector judgment, US market linkage, and event-driven analysis. The code does none of that. It only calls a market quote API for a predefined set of AI-concept stocks and indices, formats the quote data, and emits alerts when percentage moves exceed a threshold. While the code does provide real-time A-share sector-oriented monitoring and can output in plain text or JSON, that is materially narrower and different from the declared research/reporting behavior. There are no extra sensitive permissions or hidden exfiltration behaviors, but the primary functionality is mismatched.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The code’s actual function is narrow: it maps a user-provided sector name to predefined Eastmoney board codes, fetches top gainers and losers among constituent stocks, and prints a basic report or JSON. This supports only a small slice of the declared purpose—basic A-share sector trend observation. The declared description promises substantially more: global news mapping to A-shares, U.S. market linkage, identification of positive/negative catalysts, and major event reminders. None of those capabilities appear in the code. There are also no triggers or alerting behaviors, and no concrete Feishu/Coze integration beyond plain text that happens to be Markdown-like. Therefore the description materially overstates the behavior and should be considered a mismatch.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/generate_brief.js --mode sector --sector <板块名> --output pretty

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill instructs the agent to execute local Node.js scripts that fetch external data and optionally use an environment variable, but it does not declare any explicit tool scope or permission boundaries. This is dangerous because an agent/runtime may grant broader-than-necessary network or environment access implicitly, making unintended data access or outbound requests harder to govern and audit.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file is entirely framed in Chinese and the output format, labels, and instructions require Chinese-language responses, but there is no user opt-in or alternative language option. This creates a natural-language locale policy issue because the skill imposes a specific language rather than documenting a justified region-specific constraint or offering user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The entire document is written as a Chinese-only instruction/reference file and does not indicate that language selection is optional or configurable. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file is documented and implemented as an AI-industry news fetcher, with hardcoded sources limited to generic AI/technology outlets such as Yahoo Finance, Reuters, CNBC, TechCrunch, and The Verge. That does not match the manifest description of a skill focused on A股板块实时研报、全球新闻→A股映射、板块趋势研判、美股关联、利好利空、大事件提醒, because this code only collects and ranks raw AI news and performs no A-share mapping or sector-analysis logic.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The script transmits user-supplied or predefined queries to an external third-party service at api.tavily.com when Tavily mode is used. In an agent context, this can leak prompts, research intent, or potentially sensitive user-provided search terms outside the local trust boundary without explicit consent or minimization.

Content

Scanner excerpt · scripts/fetch_news.js (reported line 15)May include surrounding context.

js
*   node fetch_news.js --source tavily|web      # 强制指定数据源
 */

const TAVILY_ENDPOINT = 'https://api.tavily.com/search';

// ── 免费数据源 URL 列表 ──────────────────────────────────────────────
const FREE_SOURCES = [

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The helper saves JSON outputs into the .local directory, and this behavior is invoked across multiple modes. Although the file naming is clear in code, there is no confirmation prompt or user-facing disclosure in the help text that running the script will persist fetched/analyzed data to disk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code forces zh-CN locale and Asia/Shanghai timezone for rendered timestamps, and the surrounding output strings are also fixed in Chinese. This can violate language/locale policy when users are not given an opt-in choice or a documented reason for the restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The header text states that the tool will "only output A-share candidates" and "avoid outputting U.S. stocks," and frames this as suitable for Chinese users. This is a natural-language locale/output policy constraint that is imposed unconditionally, with no opt-in or alternative market selection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code hard-codes the locale to 'zh-CN' and Shanghai time zone in its user-facing timestamp formatting. This imposes a specific language/locale behavior without user opt-in, which matches the policy category for locale constraints.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file is written entirely in Chinese and specifies a Chinese-market role ('A股技术分析师') and Chinese output format, which effectively forces a specific language/locale. Under the policy rule, locale constraints should either be optional for the user or clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The header says the script outputs deduplicated, scored, compressed JSON '供 agent 研判', implying substantive research-ready analysis support. In practice, the code just fetches search/web results, truncates content, deduplicates them, and assigns a simple keyword-count relevance score, which is materially less than the documentation suggests.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file header, description, and usage guidance are written in Chinese only, which can force a specific language on users without offering an alternative or opt-in. The policy explicitly disallows language/locale constraints unless the skill offers a choice or clearly justifies the limitation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file’s natural-language description and usage examples are entirely in Chinese, including the required sector examples, with no indication that other languages are supported or that the locale is intentionally constrained. This can violate language/locale policy when a skill implicitly forces one language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code sends user-supplied sector-derived search keywords to an external Eastmoney search API via HTTP requests, but there is no runtime notice or confirmation informing the user that external network access will occur. Although the file header mentions the data source, the executable path itself provides no direct user-facing disclosure when the request is made.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The report timestamp is always formatted with zh-CN locale and Asia/Shanghai timezone. This is a natural-language locale policy concern because the skill forces a specific locale presentation without user opt-in or any documented justification that the tool is region-specific.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/fetch_news.js:198