Back to skill

Security audit

RSSHub Route Generator

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent, but its generated RSSHub route template can make server-side requests to untrusted article links without validation.

Review generated routes before deploying them. Add URL validation, same-origin or explicit host allowlists, redirect checks, private-network blocking, timeouts, response-size limits, and make full-text fetching opt-in before using generated code on an RSSHub server.

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
SKILL.md:96
Finding
Unrestricted server-side fetching of URLs extracted from untrusted pages## Vulnerability Details **File Location**: `SKILL.md`, lines 96-118 **Vulnerability Type**: Server-Side Request Forgery (SSRF) in generated route code **Risk Level**: Medium ### Vulnerable Code ```typescript const items = $('{list_selector}').map((_, element) => { const $el = $(element); return { title: $el.find('{title_selector}').text().trim(), link: new URL($el.find('{link_selector}').attr('href'), baseUrl).href, pubDate: parseDate($el.find('{date_selector}').text().trim(), 'YYYY-MM-DD'), category: $el.find('{category_selector}').text().trim(), }; }).get(); // 获取全文内容(可选) const fulltextItems = await Promise.all( items.slice(0, 10).map(async (item) => { try { const detailResponse = await got({ method: 'get', url: item.link }); const detail$ = load(detailResponse.data); item.description = detail$('{content_selector}').html(); return item; } catch { return item; } }) ); ``` The same unsafe fetching pattern is also recommended in `references/dev-guide.md`, lines 70-74: ```typescript const items = await pMap(list, async (item) => { if (fulltext) { const { data } = await got(item.link); item.description = load(data)('.content').html(); } ``` ### Technical Analysis The generated route obtains link destinations from HTML controlled by the remote source website. The `URL` constructor accepts absolute URLs, so an absolute `href` overrides the expected `baseUrl` origin. The resulting `item.link` is passed directly to `got` without validating: - The URL protocol. - The destination hostname. - Whether the hostname resolves to a private, loopback, link-local, or reserved address. - Redirect destinations. - Whether the destination remains on the analyzed website's approved origin. - Response size and other resource-consumption limits. ...[truncated 2453 chars]
Remediation
## Remediation Suggestions 1. Allow only `http:` and `https:` URLs. 2. Enforce an explicit hostname allowlist. For ordinary article extraction, require the destination hostname to equal the source hostname or belong to a narrowly defined set of approved origins. 3. Resolve destination hostnames before each request and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges. 4. Prevent DNS rebinding by connecting only to the validated resolved address while preserving the intended HTTP host and TLS server name. 5. Disable automatic redirects or validate the protocol, hostname, and resolved addresses of every redirect target before following it. 6. Apply strict connection, request, and overall timeouts, response-size limits, and concurrency limits. 7. Make full-text retrieval opt-in rather than automatic. 8. Reject malformed or missing `href` values before invoking the `URL` constructor. 9. Apply the same safeguards to both the primary template in `SKILL.md` and the example in `references/dev-guide.md`. 10. Use outbound firewall or proxy rules as defense in depth to prevent the RSSHub process from accessing metadata services and sensitive internal networks.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Vague Triggers

High
Confidence
99% confidence
Finding
Using any website URL as an automatic trigger is overly permissive and makes the activation boundary ambiguous, so ordinary conversation containing a URL could invoke analysis of remote content without clear consent. This is more dangerous in this skill because the next steps explicitly instruct deep crawling/analysis and route generation, potentially causing unsolicited network access, processing of adversarial pages, and downstream file creation.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill description states it analyzes arbitrary websites and outputs route code files, but it does not clearly warn users that it may fetch remote content and save generated artifacts into the working directory. Missing disclosure increases the risk of users invoking the skill without understanding the network and file-system side effects, especially when analyzing untrusted websites.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger phrases are broad everyday expressions like '帮我创建 RSS' and '生成 RSS 路由', which can cause the skill to activate in situations where the user did not clearly intend deep website analysis and code generation. In this skill, accidental activation is more risky because activation leads to network fetching of arbitrary sites and generation of files/code, expanding the chance of unintended external requests and side effects.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
L125 将输出语言固定为 `zh-cn`,属于语言/locale 的硬编码约束,文档中未说明这是可配置项,也未要求用户确认语言偏好。根据策略,未经用户选择而强制特定语言/区域设置属于自然语言政策违规。

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
This markdown file presents all user-facing guidance in a single language and does not indicate that the language choice is optional or region-specific. Under the policy criteria, forcing a specific language without user opt-in can be a natural-language policy violation.

Static analysis

No suspicious patterns detected.