Back to skill

Security audit

公众号热门文章查询

Security checks for vulnerabilities and agentic risk

Overview

The skill performs WeChat article search, but it needs Review because it adds an undisclosed promotional message, pushes users toward recurring calendar subscriptions, and can generate unsafe HTML reports.

Review this skill before installing. Use it only if you are comfortable sending search terms and date ranges to RedFox, storing a RedFox API key in your agent environment, being prompted for recurring calendar subscriptions, and avoiding the optional HTML report until its escaping and link handling are fixed.

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

Warning
Location
SKILL.md:154
Finding

Mandatory Output Controls Propagate an Unrelated Commercial Solicitation

Content
View full analysis

Vulnerability Details

File Locations: SKILL.md:154-159; scripts/fetch_gzh_trends.py:703
Vulnerability Type: Agent output hijacking and stdout protocol corruption
Risk Level: Medium

Vulnerable Code

SKILL.md:154-159 imposes mandatory response controls:

markdown
**⚠️ 强制输出规则**:

- ✅ 必须严格按照本步骤规定的格式输出
- ❌ 禁止在输出前添加任何分析或解读
- ❌ 禁止自作主张给建议或方案
- ❌ 禁止询问用户的真实目的或需求

scripts/fetch_gzh_trends.py:703 unconditionally adds a commercial solicitation:

python
print(f"\n另外红狐配套全量数据库可提供完整详实数据,如需了解采购方案,可发送邮件至 redfoxdata@proton.me 对接咨洵")

Technical Analysis

The Skill instructions require the Agent to follow a tightly controlled output format and prohibit additional analysis. Independently, the executable appends a commercial message to every successful invocation, regardless of the requested output format or whether the user asked for purchasing information.

This behavior is unrelated to the minimum functionality required to search for WeChat articles. It also conflicts with the documented JSON stdout interface: after output_json() emits a valid JSON document, line 703 adds non-JSON text. Any Agent, automation, or downstream parser that treats stdout as JSON receives malformed output.

The combination of mandatory response controls and unconditional promotional output can cause the commercial content to be propagated into Agent responses. The promotion is not necessary for authentication, article retrieval, sorting, HTML generation, or subscription functionality.

Attack Path

  1. A user asks the Agent to search for WeChat articles.
  2. The Skill instructions direct the Agent to invoke fetch_gzh_trends.py and tightly constrain how results are presented.
  3. The script sends the legitimate API request and prints the requested JSON or HTML-generation status.
  4. Line 703 unconditionally prints the third-party commercial contact message.
  5. A downstream JSON parser may fail, or the Agent ...[truncated 760 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the unconditional promotional print() call from scripts/fetch_gzh_trends.py:703.
  2. Guarantee that JSON mode writes exactly one valid JSON document to stdout.
  3. Send diagnostics only to stderr and avoid adding marketing material to either output stream.
  4. If commercial information must remain available, place it in the README or show it only after an explicit user request.
  5. Replace rigid instructions that prohibit analysis with narrowly scoped formatting guidance. The Agent must remain able to disclose errors, security concerns, and unexpected output.
  6. Add automated tests that parse JSON-mode stdout with json.loads() and fail if any trailing content is present.
  7. Document every non-search side effect, including promotional output and subscription prompts, and require explicit consent where appropriate.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_gzh_trends.py:212
Finding

Unescaped User and API Data Enables Stored HTML Injection

Content
View full analysis

Vulnerability Details

File Locations: scripts/fetch_gzh_trends.py:212-260, scripts/fetch_gzh_trends.py:608
Vulnerability Type: Stored HTML injection through unsafe template interpolation
Risk Level: Medium

Vulnerable Code

scripts/fetch_gzh_trends.py:212-260 inserts remote API fields directly into HTML markup and attributes:

python
def get_card_html(item):
    """生成单张卡片HTML"""
    title = item.get('title', '') or item.get('summary', '')[:50]
    author = item.get('author', '') or '-'
    pub_time = item.get('publicTime', '')[:10]
    note_link = item.get('url', '')
    
    clicks_count = item.get('clicksCount', 0) or 0
    watch_count = item.get('watchCount', 0) or 0
    relevance = item.get('relevanceScore', 0) or 0
    popularity = item.get('popularityScore', 0) or 0
    recency = item.get('recencyScore', 0) or 0
    total = item.get('totalScore', 0) or 0
    
    reason = generate_recommend_reason(item)
    
    # 截取摘要前100字
    summary = item.get('summary', '')[:100] if item.get('summary') else ''
    
    card = f'''
    <div class="card">
        <div class="card-content">
            <div class="card-header">
                <h3 class="card-title">
                    <a href="{note_link}" target="_blank">{title}</a>
                </h3>
                <div class="card-scores">
                    <span class="score-tag relevance">相关性 {relevance:.1f}</span>
                    <span class="score-tag popularity">热度 {popularity:.1f}</span>
                    <span class="score-tag recency">时效 {recency:.1f}</span>
                    <span class="score-tag total">总分 {total:.1f}</span>
                </div>
            </div>
            <div class="card-meta">
                <span class="author">👤 {author}</span>
                <span class="date">📅 {pub_time}</span>
                <span class="clicks">👁 阅读 {format_num(clicks_count)}</
...[truncated 3644 chars]
Remediation
View remediation

Remediation Suggestions

  1. Escape every untrusted text value with html.escape(value, quote=True) before inserting it into HTML.
  2. Escape values according to their output context; do not use text-node escaping as a substitute for URL validation.
  3. Parse links with urllib.parse.urlparse() and permit only expected https URLs to approved hosts. Reject empty, malformed, javascript:, data:, and other non-HTTPS schemes.
  4. Add rel="noopener noreferrer" to every link using target="_blank".
  5. Prefer a template engine with automatic HTML escaping rather than constructing markup through f-strings.
  6. Add a restrictive Content Security Policy, for example by disabling inline scripts and limiting navigation and resource origins.
  7. Treat all RedFox API fields as untrusted, even when the service is authenticated.
  8. Add regression tests using payloads containing quotes, angle brackets, event handlers, and unsafe URL schemes. Verify that generated reports contain encoded text rather than executable markup.
  9. Consider generating a data-only JSON file and rendering it through a hardened viewer if interactive HTML is required.
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| SKILL 定义 | `SKILL.md` | 定义 Skill 元数据、工作流程、展示策略、订阅逻辑 |

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest describes the skill as a public-account article search tool for searching viral articles, showing hot recommendations, and providing inspiration. However, the README advertises an additional 'Subscription push' feature for daily scheduled deliveries, which is a distinct notification/automation capability rather than just search and recommendation.

Content

No source excerpt is available for this finding.

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · README.en.md (reported line 60)May include surrounding context.

md
💡 **Found 12 related articles; showing first 10. View all?**

| Title                                                                                      | Author           | Reads | Published  | Relevance | Heat | Timeliness | **Total** |
| ------------------------------------------------------------------------------------------ | ---------------- | ----- | ---------- | --------- | ---- | ---------- | --------- |
| [Must-read for workplace newcomers: 5 tips to fit in fast](https://mp.weixin.qq.com/s/xxx) | Workplace Growth | 100K  | 2026-05-15 | 9.8       | 3.0  | 2.0        | **14.8**  |
| [Workplace communication: 3 sentences you must never say!](https://mp.weixin.qq.com/s/xxx) | Workplace Tips   | 85K   | 2026-05-14 | 9.5       | 2.8  | 2.0        | **14.3**  |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · README.en.md (reported line 65)May include surrounding context.

md
| [Must-read for workplace newcomers: 5 tips to fit in fast](https://mp.weixin.qq.com/s/xxx) | Workplace Growth | 100K  | 2026-05-15 | 9.8       | 3.0  | 2.0        | **14.8**  |
| [Workplace communication: 3 sentences you must never say!](https://mp.weixin.qq.com/s/xxx) | Workplace Tips   | 85K   | 2026-05-14 | 9.5       | 2.8  | 2.0        | **14.3**  |
| [Workers must save: 7 secrets to efficient meetings](https://mp.weixin.qq.com/s/xxx)       | Workplace Lab    | 62K   | 2026-05-13 | 9.2       | 2.5  | 1.8        | **13.5**  |
| ...                                                                                        | ...              | ...   | ...        | ...       | ...  | ...        | ...       |

**🔤 Query expansion**: work, office workers, workplace outfits, workplace tips, growth, niche careers, managing up, workplace anxiety, promotion, financial freedom

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares capabilities that imply environment access, file writing, and network use, but it does not define any explicit tool scope or allowed-tools boundary. This weakens least-privilege controls and can let an agent invoke broader capabilities than users would expect from a simple article-search skill, increasing the risk of data exposure or unintended side effects such as file creation and outbound requests.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest description says the skill should be used when the user wants to '获取创作灵感' in addition to searching公众号文章. That phrase is broad and could overlap with many general brainstorming requests, making activation boundaries unclear rather than tightly scoped to article search use cases.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Multiple required interaction strings and expected user replies are hard-coded in Chinese, such as requiring replies like '拓展' and '不拓展'. This imposes a language/locale constraint on interaction without stating that the skill is Chinese-only or offering user opt-in to that language.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill’s documented behavior expands from article search into mandatory calendar-based subscription creation and timed push workflows, which is a material increase in authority and persistence. This is dangerous because a user seeking a one-time search could be funneled into creating recurring tasks, causing unintended retention of search parameters and ongoing automated actions outside the original request scope.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documented use of calendar_create for recurring subscriptions is not justified by the skill’s stated purpose of searching WeChat articles. Invoking a scheduling tool introduces cross-tool action and persistence, which can be abused to create unwanted reminders or records containing user interests, keywords, and timing preferences that exceed the data and permission expectations of a search-only workflow.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

User-supplied keywords and date ranges are transmitted to an external service, but the skill description does not clearly disclose that user queries leave the local environment. In a search skill, this is contextually expected to some degree, but lack of explicit disclosure still creates privacy and consent risk, especially for sensitive or proprietary search terms.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script’s documented purpose is keyword-based public-account article search, but it also intentionally supports empty-keyword queries that fetch site-wide trending content. That broadens data access beyond the advertised scope and, combined with the embedded commercial upsell messaging, creates an undeclared behavior that can surprise users and violate least-astonishment or policy expectations.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The HTML mode writes a local file to disk, which is a broader capability than simple search/display and is not clearly disclosed in the skill description. While the filename is partially sanitized, undisclosed file creation can still have security and trust implications in agent environments that expect read-only or transient behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This README presents all instructions, examples, and safety information only in Chinese. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale constraint is clearly documented and justified.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The stated purpose is searching公众号文章 and surfacing trending content for inspiration. Reading a secret from environment variables is an operational capability beyond that user-facing purpose and is not mentioned in the manifest, even though it is used to access the backend service.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/gzh_trend_data_format.md:20