Back to skill

Security audit

今日头条热榜 | Toutiao Hot News

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Toutiao trend-collection purpose, but it needs review because it includes an unsafe HTML report renderer and a script that can execute code from a hard-coded external local skill path.

Review before installing. The normal documented commands fetch public Toutiao data and may write a local SQLite database and HTML report under data/. Avoid using scripts/fetch-toutiao.py unless it is changed to call the bundled script, and do not open generated reports from untrusted or tampered data until the HTML rendering is fixed to safely escape remote content.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_html.py:225
Finding

Stored Cross-Site Scripting in Generated HTML Reports

Content
View full analysis
{ if (dateSelect && item.date !== dateSelect) return false; if (search && !item.title.toLowerCase().includes(search)) return false; return true; }); document.getElementById('showCount').textContent = filtered.length; const container = document.getElementById('hotList'); if (filtered.length === 0) { container.innerHTML = `
📰
没有找到记录
`; return; } const grouped = {}; filtered.forEach(item => { if (!grouped[item.date]) grouped[item.date] = []; grouped[item.date].push(item); }); let html = ''; Object.keys(grouped).sort().reverse().forEach(date => { html += grouped[date].map(item => `
${item.rank}
${item.title}
${item.label ? `${item.label}` : ''} ${item.popularity ? `🔥 ${formatHeat(item.popularity)}` : ''}
Remediation
View remediation
` block. Store it in a non-executable JSON element or external JSON file. If inline embedding is required, escape HTML-significant characters, including replacing `<` with `\u003c`. 4. Add `rel="noopener noreferrer"` to links opened with `target="_blank"`. 5. Add a restrictive Content Security Policy that disallows inline scripts and limits connections and navigation to required destinations. 6. Treat all API and database values as untrusted, even when the current provider is expected to be legitimate. 7. Regenerate the checked-in `data/index.html` after correcting the generator because the existing artifact contains the same unsafe rendering logic. ]]>

T07 · Tool Hijacking and Spoofing

Warning
Location
scripts/fetch-toutiao.py:16
Finding

Execution of an External Mutable Skill Script Outside the Audited Package

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The skill claims to fetch and output trending data, but it also initializes and manages persistent local storage and logs fetch activity to a database. Undisclosed persistence can surprise users, retain data longer than expected, and enable accumulation of local artifacts that other tools or users may later consume without understanding provenance or sensitivity.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

The skill claims to fetch and output trending data, but it also initializes and manages persistent local storage and logs fetch activity to a database. Undisclosed persistence can surprise users, retain data longer than expected, and enable accumulation of local artifacts that other tools or users may later consume without understanding provenance or sensitivity.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill documentation advertises executable behaviors that require network access, shell execution, and local file/database writes, but it does not declare any tool scope or permissions boundaries. This is dangerous because users and agents cannot clearly understand or constrain what the skill is allowed to do, increasing the chance of unintended filesystem changes, persistent data creation, or network activity.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest says the skill outputs titles, heat values, and links, but the body also documents database persistence and HTML report generation. This incomplete disclosure is a security-relevant integrity issue because users may authorize a lightweight fetch skill without realizing it writes files and produces local artifacts.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The overview presents the skill as a hot-board fetcher, but later sections add historical collection and persistence capabilities that materially change the trust model. Hidden or underemphasized stateful behavior is dangerous because it can lead to unnoticed accumulation of local data and broader operational privileges than the overview suggests.

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/fetch-toutiao.py (reported line 23)May include surrounding context.

python
cmd = ['node', str(script_path), 'hot', str(limit)]
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        if result.returncode == 0:
            data = json.loads(result.stdout)
            print(f"   ✅ 抓取到 {len(data)} 条热榜")

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The generated HTML sets lang="zh-CN", and the page content is also fixed in Chinese throughout the file. Under the policy rules, forcing a specific language/locale without user opt-in or documented justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill description says it outputs trending titles, heat values, and links, but this code also persists fetched data and fetch logs into a local database. That undisclosed data-retention capability expands the skill's behavior beyond its stated purpose, which is dangerous because hidden persistence can enable silent collection, profiling, or later secondary use without operator awareness.

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/save_to_db.py (reported line 25)May include surrounding context.

python
try:
        # 调用原有Node.js脚本获取数据
        result = subprocess.run(
            ['node', str(node_script), 'hot', str(limit)],
            capture_output=True,
            text=True,

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The HTML document declares lang="zh-CN", and the visible interface text throughout the page is only in Chinese. Under the policy rule, forcing a specific language without user opt-in or a documented region-specific justification is a natural-language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module title and descriptive text are entirely in Chinese, and the script's user-facing messages are also fixed to Chinese throughout the file. This indicates a language-specific skill experience without any visible opt-in or justification that the tool is intended only for a Chinese-speaking or region-specific context.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest says the skill outputs trending titles, heat values, and links from Toutiao hot lists. The query_logs command instead reads and prints internal collection metadata from fetch_logs such as crawl times, counts, and status, which is operational information not described as part of the skill's user-facing purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
74% confidence
Finding

The skill's stated purpose is to retrieve Toutiao trending data, which reasonably implies network access and parsing, but not necessarily spawning a separate runtime via subprocess. Launching an external Node.js process adds execution capability beyond the manifest's stated intent and is not disclosed there.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The Accept-Language header is fixed to prefer zh-CN and Chinese content first. This is a natural-language locale constraint that does not offer user opt-in or configuration, which can violate language/locale policy requirements for user choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.