Back to skill

Security audit

social-reader

Security checks for vulnerabilities and agentic risk

Overview

The skill largely matches its social-media review purpose, but its URL fetching and local review server are under-protected enough that crafted input or local web content could read or change review data or trigger LLM calls.

Review before installing. Use only trusted, exact X/Twitter status URLs, avoid running the review server while browsing untrusted sites, and do not process private or regulated content unless you are comfortable sending it to the configured fetch and LLM providers. Prefer a fixed trusted LLM endpoint, a temporary API key, and local firewall or sandbox controls until the URL validation and review API authentication are fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
fetcher.py:5
Finding

Server-Side Request Forgery Through Insufficient URL Validation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
notifier.py:71
Finding

Unauthenticated Local Review API Exposed to Arbitrary Web Origins

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
notifier.py:332
Finding

Stored HTML and Script Injection Through Unescaped Original URL

Content
View full analysis
d.status === 'pending_review'); const reviewed = drafts.filter(d => d.status === 'approved' || d.status === 'rejected'); document.getElementById('subtitle').textContent = `待审阅 ${pendingReview.length} 条 · 已处理 ${reviewed.length} 条`; document.getElementById('archiveBtn').disabled = reviewed.length === 0; const container = document.getElementById('cards'); if (drafts.length === 0) { container.innerHTML = '
暂无草稿
'; return; } container.innerHTML = drafts.map((d, i) => { const regenBadge = d.regenerated ? `已重写 ${d.regenerated} 次` : ''; const isApproved = d.status === 'approved'; const isRejected = d.status === 'rejected'; return `
@${escapeHtml(d.original_username || '?')}
${regenBadge} ${d.char_count || '?'} 字
原文摘要

${escapeHtml((d.original_text || '').substring(0, 200))}

查看原推
AI 锐评草稿

${escapeHtml(d.commentary || '')}

`; }).join(''); } ``` The URL is persisted without normal ...[truncated 2797 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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code chunk implements a narrowly scoped fetcher for a single X/Twitter post or article. It parses X/Twitter URLs, calls api.fxtwitter.com and cdn.syndication.twimg.com, and returns structured content such as text, author, media, and engagement counts. It does not contain any scheduling, batch processing, patrol/monitoring, notification delivery, or LLM-based distillation behavior described in the declaration. While the declared description includes single post reading, the broader claimed capabilities are not represented in this code, making the description materially broader than the actual behavior shown.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description emphasizes social media scraping/automation, real-time post reading, scheduled batch patrol, LLM distillation, and review notifications. The supplied code does not perform scraping, post reading, or scheduling. Instead, its primary purpose is a local human-in-the-loop review interface for already-generated tweet commentary drafts, with persistence to local JSON files and optional regeneration via an LLM. While 'review notifications' is partially represented by the desktop popup/open-browser behavior, that is only a small subset of the actual functionality. The code therefore has a materially different primary purpose and includes undeclared capabilities such as hosting an HTTP server and mutating local draft/archive state.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The declared description presents a broader social-media scraping and automation skill with multiple capabilities: reading posts in real time, scheduled patrol, LLM distillation, and review notifications. The supplied code chunk implements only one subset of that description: LLM distillation of already-collected tweet/article data from a local JSON file. It does not scrape content, connect to social platforms, schedule patrols, process triggers, or send notifications. Because the actual code’s primary purpose is narrower and materially different from the declared end-to-end automation description, this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documents capabilities that involve environment variables, local file reads/writes, network access, and shell execution, but it does not declare any explicit tool scope or permissions boundary. This is dangerous because an agent or runtime may grant broader access than users expect, increasing the risk of unintended file modification, external requests, or command execution during normal use.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Pipeline mode sends scraped post content to an external LLM API, but the documentation omits a privacy warning and data-handling notice. This is dangerous because users may unknowingly transmit monitored content, potentially including sensitive or regulated data, to a third-party service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code sends user-supplied X/Twitter URLs directly to api.fxtwitter.com, a third-party service, and also sends tweet identifiers to X syndication endpoints without any visible consent, disclosure, or minimization. In a social-media scraping skill, this matters because queried URLs can reveal user interests, monitoring targets, or investigation subjects to external services, creating a privacy and data-handling risk even if no code execution occurs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module docstring and embedded UI text are entirely in Chinese and the HTML explicitly sets lang="zh-CN", which indicates the skill is designed to operate in a fixed locale. There is no visible mechanism offering users a language choice or documenting that the locale restriction is intentional and limited to a region-specific use case.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes scraping, scheduled patrol, LLM distillation, and review notifications. While notifications are in scope, this implementation uses OS-level PowerShell subprocess execution, which is a broader host-execution capability than is obviously required for that purpose. A local review UI could notify without invoking shell-capable system tooling.

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 · notifier.py (reported line 515)May include surrounding context.

python
try:
        import subprocess
        msg = f"共 {len(pending)} 条推文锐评待审阅"
        subprocess.Popen(
            ["powershell", "-Command",
             f"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null; "
             f"[System.Windows.Forms.MessageBox]::Show('{msg}', '推文审阅提醒')"],

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The top-level documentation describes reading pending_tweets.json, calling the LLM, and outputting to drafts.json, which implies a transformation/output step only. In addition, the implementation clears pending_tweets.json after processing, which is a material side effect not disclosed by the docstring.

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 · SKILL.md (reported line 35)May include surrounding context.

md
配置方式(环境变量):
  LLM_API_KEY     - API 密钥(必须)
  LLM_BASE_URL    - API 端点(默认 https://api.openai.com/v1)
  LLM_MODEL       - 模型名称(默认 gpt-4o-mini)
"""

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 · processor.py (reported line 8)May include surrounding context.

python
配置方式(环境变量):
  LLM_API_KEY     - API 密钥(必须)
  LLM_BASE_URL    - API 端点(默认 https://api.openai.com/v1)
  LLM_MODEL       - 模型名称(默认 gpt-4o-mini)
"""

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The built-in system prompt explicitly instructs the model to '使用中文输出', which imposes a language choice. The file does not offer a user-selectable language option or indicate that this locale restriction is optional or justified as region-specific.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The base URL for the LLM API is fully controlled by an environment variable with no validation or allowlisting. This allows redirection of all processed content and the Authorization bearer token to an arbitrary endpoint, creating a strong exfiltration and credential-leak risk if the environment is misconfigured or attacker-influenced.

Content

Scanner excerpt · processor.py (reported line 43)May include surrounding context.

python
return {
        "api_key": api_key,
        "base_url": os.environ.get("LLM_BASE_URL", "https://api.openai.com/v1"),
        "model": os.environ.get("LLM_MODEL", "gpt-4o-mini"),
    }

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

The code performs outbound HTTP transmission of model prompts containing tweet/article content to an external API. In the context of a social-content processing skill, this materially increases privacy and confidentiality risk because untrusted or sensitive collected content can be exfiltrated outside the local environment by default.

Content

Scanner excerpt · processor.py (reported line 67)May include surrounding context.

python
}

    try:
        resp = requests.post(
            f"{config['base_url']}/chat/completions",
            headers=headers,
            json=payload,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Tweet and article content is sent to a third-party LLM endpoint without any explicit user-facing notice, consent, or data-classification guardrails. If the queued content includes private, sensitive, embargoed, or regulated material, this causes unreviewed external data disclosure to a provider selected by configuration.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest describes a broader social media scraping and automation skill with real-time reading, scheduled batch patrol, distillation, and review notifications. This file's actual behavior is narrower and different in emphasis: it reads a local pending_tweets.json queue, calls an LLM, writes drafts.json, and clears the pending queue, with no scraping, patrol scheduling, or notification behavior present here.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The prompt implements social-media post generation with a strong persona and opinionated output, which materially differs from the declared skill purpose of reading, scraping, distillation, and review notification. This kind of capability mismatch is dangerous because it can cause the agent to generate unsolicited public-facing content or persuasive messaging in workflows that users expect to be passive analysis, increasing the risk of misuse, brand harm, or unintended automation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This file's natural-language docstrings and console messages are presented exclusively in Chinese, with no indication that users may select another language or locale. The policy for this category flags language-forcing behavior when a specific language is imposed without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This JSON file contains multiple human-facing labels written entirely in Chinese, with no indication that the skill supports user language selection or that it is intentionally limited to a Chinese-speaking locale. Under the policy for natural-language violations, forcing a specific language without user opt-in can be a locale policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring presents the skill name, usage instructions, and output description entirely in Chinese, with no indication that other languages are supported or that the user can choose a locale. This is a natural-language locale policy concern because the skill appears to impose a specific language by default rather than offering an opt-in or documented justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill states that pipeline mode starts a local HTTP review server and opens a browser page, but it does not present this as a clear user warning. This is dangerous because local services and automatic browser launches expand the attack surface and may surprise users in restricted or multi-user environments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file's natural-language docstrings, comments, and user-visible error messages are written exclusively in Chinese, which imposes a specific language choice without any indication of user opt-in or locale justification. Under the language/locale policy, a skill should not force a language unless it is documented as intentional and context-specific.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This plain text file says it contains 'Twitter URL input list' and shows a single tweet URL example, but it does not clearly constrain what kinds of URLs are allowed beyond that example. Without an explicit statement such as 'tweet/status URLs only' or disallowed examples, the trigger/input scope is underspecified and could lead to unintended inputs being treated as valid.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The inline documentation presents notify() as a simple startup helper with three actions, but the actual function additionally enters a long-running HTTP server loop and exposes mutable API endpoints until interrupted. This is more than missing detail because the documented intent understates the persistent server behavior and side effects.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.