T09 · Insecure Skill Coding Practices
- Location
scripts/scanner.py:174- Finding
SSRF Validation Fails Open When DNS Resolution Fails or Times Out
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a coherent RSS reader, but its URL-fetching safety checks are weak enough that users should review it before installing.
Install only if you are comfortable with an RSS tool making outbound requests from the agent host and storing subscription/article history locally. Avoid importing untrusted OPML files or adding attacker-controlled feeds in sensitive networks, disable auto_purge if you want manual retention control, and treat fetched article text as untrusted content when asking the agent to summarize it.
scripts/scanner.py:174SSRF Validation Fails Open When DNS Resolution Fails or Times Out
scripts/scanner.py:190DNS Rebinding and Resolution TOCTOU Bypass in SSRF Protection
scripts/scanner.py:358Untrusted Feed Content Is Exposed to the Agent Without Prompt-Injection Boundaries
The purge_articles method executes a DELETE against stored articles and commits the change, making it an irreversible destructive operation. Although the docstring explains the method, this code file provides no user-facing warning, prompt, or other disclosure for the data deletion.
The skill documents commands that perform network access and write persistent local state, but the manifest shown in SKILL.md does not declare any explicit tool scope, permissions, or allowed-tools boundary. That creates a trust and review gap: an agent may invoke broader capabilities than a user expects, especially because the skill also references auxiliary fetching tools and automation.
This markdown file consistently mandates a single language for descriptions, examples, and operational guidance, but it does not indicate that the skill is region-specific or that users may opt into another language. That creates a natural-language policy concern because the skill effectively forces one locale without user choice.
The skill prominently supports automatic article retrieval, optional external fetching tools, and persistent SQLite storage, yet it does not give a clear upfront privacy and side-effect warning. Users may not realize that using the skill causes outbound requests to third-party sites and stores browsing/subscription history locally, which can expose sensitive interests or internal URLs if used with private feeds.
The request headers force Accept-Language: en-US,en;q=0.5, which imposes a specific language/locale preference regardless of the user's own settings or content locale. This is a natural-language policy concern because the file otherwise contains no user choice, opt-in, or region-specific justification for overriding locale.
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
redirect_url = urljoin(url, redirect_url)
_validate_url_safe(redirect_url)
url = redirect_url
resp = requests.get(
url, timeout=min(timeout, remaining), headers=REQUEST_HEADERS,
allow_redirects=False, stream=True,
)
The module-level description and many user-oriented docstrings/comments are written exclusively in Chinese, which indicates a language-specific presentation without any visible mechanism for user language selection. Under the stated policy, forcing a specific language without opt-in can be a locale/language policy violation.
The remove_blog method deletes blog records, and due to the foreign key cascade, associated articles may also be deleted. While there is an internal docstring describing the behavior, there is no user-facing confirmation, prompt, or visible disclosure in this file for this destructive action.
The mark_all_read method can update all unread articles globally or by category/blog in a single call, which is a potentially high-impact state-changing operation. This file contains no visible prompt, log, or user disclosure warning that such a bulk update is occurring.
This Python skill presents its top-level description, usage text, and extensive command/help output in Chinese, and there is no visible option for the user to select another language or locale. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.
该技能说明从开头即完全以中文呈现,未见提供多语言选项、用户语言偏好机制,或声明这是仅面向特定中文用户群的区域性技能。按规则,强制单一语言且无用户选择可构成语言/locale 策略问题。
The scan workflow combines automatic network fetching, background/silent execution, and automatic deletion of stored content after scans, but the command documentation does not present these side effects together where users invoke scan. This can lead to unintended network activity and unexpected data loss or audit gaps, especially when run via cron or silent mode.
The dependency is specified with only a lower bound, so builds may resolve to different versions over time. This weakens supply-chain reproducibility and can accidentally introduce vulnerable or breaking releases, especially for a network-facing RSS tool that fetches remote content.
requests>=2.20.0
defusedxml>=0.7.0
beautifulsoup4>=4.9.0
The manifest does not pin requests, and that package has multiple known advisories across versions, so there is no assurance that deployments avoid affected releases. Because this skill retrieves remote URLs and may handle redirects, credentials, and attacker-controlled endpoints, an unsafe requests version could materially increase exposure.
The dependency is not pinned to a specific version, which makes installations non-reproducible and increases supply-chain risk. Although defusedxml is a defensive library, leaving it unpinned can still result in unexpected version changes or regressions.
requests>=2.20.0
defusedxml>=0.7.0
beautifulsoup4>=4.9.0
Using an unpinned beautifulsoup4 version allows future installs to pull different releases, reducing build determinism and increasing supply-chain exposure. In a scraper/RSS reader that parses untrusted HTML, unexpected parser behavior changes can affect security posture or stability.
requests>=2.20.0
defusedxml>=0.7.0
beautifulsoup4>=4.9.0