Back to skill

Security audit

News Aggregator Skill

Security checks for vulnerabilities and agentic risk

Overview

This news skill mostly matches its stated purpose, but its deep-fetch mode can request arbitrary article URLs without enough safeguards, creating a real review concern before installation.

Install only if you are comfortable with a news skill making outbound web requests, including deep-fetching article links from public feeds. Prefer running it in an isolated environment with restricted network egress, avoid --deep on untrusted or broad sources, pin dependencies before installing, and review generated reports because content is automatically saved under reports/.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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/fetch_news.py:24
Finding
Server-Side Request Forgery Through Unvalidated Deep-Fetch URLs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch_news.py:24-35, 48-50` **Vulnerability Type**: Server-Side Request Forgery caused by insufficient URL validation **Risk Level**: High ### Vulnerable Code ```python def fetch_url_content(url): """ Fetches the content of a URL and extracts text from paragraphs. Truncates to 3000 characters. """ if not url or not url.startswith('http'): return "" try: response = requests.get(url, headers=HEADERS, timeout=5) response.raise_for_status() soup = BeautifulSoup(response.content, 'html.parser') ``` ```python def enrich_items_with_content(items, max_workers=10): with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: future_to_item = {executor.submit(fetch_url_content, item['url']): item for item in items} ``` The deep-fetch feature is enabled through the documented `--deep` option in `SKILL.md:24, 38, 44, 52`. ### Technical Analysis Article URLs are obtained from remote feeds and user-generated sources, including Hacker News and V2EX. The only validation performed before issuing an HTTP request is: ```python url.startswith('http') ``` This check does not: - Parse and restrict the URL scheme to exact `http` or `https` values. - Reject loopback, private, link-local, reserved, multicast, or unspecified IP addresses. - Protect against hostnames that resolve to internal addresses. - Restrict requests to approved external domains. - Validate redirect destinations. `requests.get()` follows HTTP redirects by default. Consequently, even a URL initially hosted on a public domain can redirect the request to an internal network destination. Concurrent processing also permits several attacker-controlled URLs to be requested during one deep-fetch operation. ### Attack Path 1. An attacker submits or controls an item on a supported user-generated news source. 2. The item contains a direct URL to an internal HTTP servi ...[truncated 1258 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse URLs using `urllib.parse.urlsplit()` and permit only exact `http` and `https` schemes. 2. Require a nonempty hostname and reject embedded credentials or malformed authority components. 3. Resolve the hostname before connecting and reject all loopback, private, link-local, multicast, reserved, and unspecified IPv4 and IPv6 addresses using Python's `ipaddress` module. 4. Prevent DNS rebinding by ensuring the validated address is the address actually used for the connection, preferably through a hardened HTTP client or controlled egress proxy. 5. Disable redirects with `allow_redirects=False`, or manually follow redirects while repeating the complete validation process for every destination. 6. Prefer an explicit allowlist of approved content domains when operationally feasible. 7. Run deep fetching in a sandbox with network access restricted to the public Internet and with cloud metadata endpoints blocked. 8. Add response-size and content-type limits to reduce resource consumption and prevent retrieval of unexpected binary data. 9. Add automated tests covering loopback addresses, RFC1918 ranges, link-local addresses, IPv6 private addresses, encoded addresses, DNS aliases, and redirect chains. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned Third-Party Dependencies Create a Mutable Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-2`; installation references in `README.md:47, 77` **Vulnerability Type**: Unpinned third-party package installation **Risk Level**: Medium ### Vulnerable Code `requirements.txt` contains: ```text requests beautifulsoup4 ``` The README instructs users to install these mutable dependencies: ```bash pip install -r requirements.txt ``` It also documents an NPX-based installation without an explicit package version: ```bash npx skills add https://github.com/cclank/news-aggregator-skill ``` ### Technical Analysis Neither Python dependency has an exact version constraint or an integrity hash. A future installation can therefore resolve to package versions different from those originally tested or audited. The documented NPX workflow similarly invokes the `skills` package without an explicit version. Package installation can execute package-controlled installation logic with the privileges of the invoking user. Although no currently malicious dependency was identified in the reviewed files, the installation process is not reproducible and trusts mutable upstream releases. This creates exposure to: - A compromised future dependency release. - An upstream account or package takeover. - Unexpected security or compatibility regressions. - Changes in dependency resolution over time. - Compromise of the unpinned NPX package used during installation. ### Attack Path 1. An upstream Python or NPX package publishes a compromised or unexpectedly unsafe release. 2. A user follows the documented installation instructions at a later date. 3. The package manager resolves the latest compatible release because no reviewed version is pinned. 4. Package installation logic or imported package code executes in the user's environment. 5. Malicious code could act with the privileges and network/filesystem access of the user running the installation or Skill. ### Impact Assessment If an upstream package i ...[truncated 649 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to an exact, reviewed version. 2. Generate and commit a lock file that includes all transitive dependencies. 3. Use integrity hashes, such as a hash-locked requirements file generated with `pip-compile --generate-hashes`. 4. Pin the NPX package to an explicitly reviewed version instead of allowing mutable resolution. 5. Install dependencies inside a dedicated virtual environment or isolated container without administrative privileges. 6. Use trusted package indexes and disable unexpected supplemental indexes to reduce dependency-confusion exposure. 7. Add automated dependency vulnerability scanning and update pins through reviewed change requests. 8. Document the tested Python version and dependency-update procedure so installations remain reproducible. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (17)

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The phrase '自动生成杂志级排版的中文日报/周报' specifies Chinese-language output as a default behavior, but the README does not mention any option for users to choose another language. This creates a natural-language locale policy concern because it imposes a language preference without explicit opt-in or documented justification.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding
The README instructs users to install the skill via `npx skills add` from a remote source without pinning an exact package version or commit. This creates a supply-chain risk: a later malicious or compromised package/repository state could be fetched and executed during installation.

Skill Enumeration

Medium
Category
Agent Snooping
Content
git clone git@github.com:cclank/news-aggregator-skill.git

# 2. 定位或创建项目的 skills 目录
mkdir -p YourProject/.claude/skills

# 3. 将整个文件夹复制过去
cp -r news-aggregator-skill YourProject/.claude/skills/
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Session Persistence

Medium
Category
Rogue Agent
Content
git clone git@github.com:cclank/news-aggregator-skill.git

# 2. 定位或创建项目的 skills 目录
mkdir -p YourProject/.claude/skills

# 3. 将整个文件夹复制过去
cp -r news-aggregator-skill YourProject/.claude/skills/
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
git clone git@github.com:cclank/news-aggregator-skill.git

# 2. 定位或创建项目的 skills 目录
mkdir -p YourProject/.claude/skills

# 3. 将整个文件夹复制过去
cp -r news-aggregator-skill YourProject/.claude/skills/
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Skill Enumeration

Medium
Category
Agent Snooping
Content
cp -r news-aggregator-skill YourProject/.claude/skills/

# 4. 验证:确保 SKILL.md 存在于目标目录
ls YourProject/.claude/skills/news-aggregator-skill/SKILL.md
```

### 第二步:安装 Python 依赖(如果你的agent足够聪明,可以跳过)
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
cp -r news-aggregator-skill YourProject/.claude/skills/

# 4. 验证:确保 SKILL.md 存在于目标目录
ls YourProject/.claude/skills/news-aggregator-skill/SKILL.md
```

### 第二步:安装 Python 依赖(如果你的agent足够聪明,可以跳过)
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The natural-language activation examples are broad and overlap with ordinary user requests like asking for news on AI, finance, or open source. In an agent environment, vague triggers can cause unintended invocation of the skill, leading to unexpected network access, data fetching, or execution paths the user did not explicitly approve.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill invokes a network-capable script (`fetch_news.py`) but does not declare any `permissions` or `allowed-tools` scope. This weakens least-privilege controls and can cause the runtime or reviewer to underestimate the skill's access, increasing the chance of unintended outbound requests or misuse if the skill is modified later.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The phrase allowing invocation on 'similar menu/help triggers' is overly broad and can cause the skill to activate on vague user language that was not intended to run this skill. Ambiguous triggers increase the risk of unauthorized or surprising actions, especially because the skill can read local files and initiate network-backed workflows.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This is a natural-language policy issue applicable to all file types. The instruction fixes the response language to Simplified Chinese, but the file does not offer user opt-in, language selection, or a documented region-specific justification, which can violate language/locale choice expectations.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs automatic writing of timestamped reports to `reports/` for every run without notifying the user or requesting consent. Silent filesystem modification can leak sensitive fetched content into persistent storage, create clutter, and violate user expectations about side effects.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The skill header and interaction instruction require the user to reply in Chinese or copy a provided Chinese command, which imposes a language choice without explicit user opt-in. This can mislead or exclude users, reduce transparency about what the skill will do, and create prompt-routing issues when the surrounding system or user expects another language.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The template includes a very broad invocation phrase for a 'global scan' across all sources without meaningful scoping, constraints, or user-confirmation steps. Broad trigger phrasing can cause the skill to activate for loosely related requests and encourage high-cost or unintended multi-source retrieval, which increases the chance of overreach, irrelevant collection, and abuse of the skill beyond the user's precise intent.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests
beautifulsoup4
Confidence
94% confidence
Finding
The dependency 'requests' is unpinned, which makes builds non-reproducible and can cause the skill to install an unexpected or newly vulnerable version over time. In a network-facing news aggregation skill that fetches content from multiple external sources, this increases supply-chain and reliability risk because dependency behavior may change without review.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding
The manifest does not pin a version of 'requests', and that package has multiple historical advisories, including issues related to credential leakage and TLS/session verification behavior. Because this skill retrieves data from external sites, an affected installed version could expose network traffic integrity or sensitive credentials if the environment uses features like .netrc or persistent sessions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests
beautifulsoup4
Confidence
92% confidence
Finding
The dependency 'beautifulsoup4' is also unpinned, so installations may resolve to different versions across environments or at different times. While this is typically lower severity than direct code execution flaws, it still creates supply-chain uncertainty and can introduce vulnerable or incompatible releases into a scraper that processes untrusted remote content.

Static analysis

No suspicious patterns detected.