Back to skill

Security audit

ai-news-daily-v1.0.4

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly behaves like a Chinese AI-news fetcher, but it has review-worthy risks from unvalidated article fetching, third-party translation, and non-reproducible dependency installation.

Install only if you are comfortable running a networked news fetcher in an isolated environment. Restrict outbound access if possible, review the RSS and article-fetch behavior, pin dependencies before installing, and be aware that article text may be stored locally and sent to third-party translation APIs. Treat the advertised automatic OpenClaw scheduling/push feature as unsupported by the inspected code unless another platform mechanism supplies it.

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
src/daily_fetch.py:378
Finding
Server-Side Request Forgery Through Unvalidated RSS Article URLs<![CDATA[ ## Vulnerability Details **File Location**: `src/daily_fetch.py:282-306`, `src/daily_fetch.py:378-397` **Vulnerability Type**: Server-Side Request Forgery (SSRF) **Risk Level**: High ### Vulnerable Code ```python def fetch_article_content(url, source_name, config): """抓取文章正文 - 保存完整内容供AI生成摘要""" try: headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'} timeout = config['fetch']['request_timeout'] max_retries = config['fetch']['max_retries'] delay = config['fetch']['retry_delay'] # 使用 trafilatura 抓取 if USE_TRAFILATURA: try: downloaded = trafilatura.fetch_url(url) if downloaded: text = trafilatura.extract( downloaded, include_comments=False, include_tables=False, no_fallback=True, target_language='zh' ) if text and len(text) > 100: return text[:config['output']['raw_content_length']] except Exception as e: logging.warning(f"[trafilatura] 抓取失败 {source_name}: {e}") # 备用:BeautifulSoup resp = fetch_with_retry(url, headers, timeout, max_retries, delay) ``` The URL is obtained from an RSS entry and passed directly to the vulnerable fetch routine: ```python for entry in feed.entries[:30]: title = entry.get('title', '').strip() url = entry.get('link', '') if not title or not url: continue # 检查时间 published = entry.get('published_parsed') or entry.get('updated_parsed') if published: pub_date = datetime(*published[:6]) if pub_date < cutoff_date: continue rss_summary = re.sub(r'<[^>]+>', '', entry.get('summary', '')) is_dup, article = deduplicator.is_duplicate(url, title, rss_summary) if is_dup: if article: items.append(article) ...[truncated 2827 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Accept only `https` article URLs and reject URLs containing credentials or malformed hostnames. 2. Maintain an allowlist mapping each RSS source to its permitted article domains. 3. Resolve the hostname before connecting and reject every loopback, private, link-local, multicast, unspecified, and reserved IPv4 or IPv6 address. 4. Disable automatic redirects or validate the scheme, hostname, and resolved address of every redirect target. 5. Protect against DNS rebinding by connecting to the already validated address while preserving TLS hostname verification. 6. Apply the same validation to both `trafilatura.fetch_url()` and the fallback request path. Prefer one centrally controlled HTTP client so policies cannot be bypassed. 7. Block access to cloud metadata addresses and internal networks through host-level egress controls as defense in depth. 8. Impose response-size and content-type limits before parsing or storing a response. 9. Add tests covering direct private-IP URLs, IPv6 loopback, alternative IP representations, DNS rebinding, and public-to-private redirects. ]]>

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned Third-Party Dependencies Permit Unreviewed Package Upgrades<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-6` **Vulnerability Type**: Non-reproducible and insufficiently constrained dependency installation **Risk Level**: Medium ### Vulnerable Code ```text requests>=2.28.0 feedparser>=6.0.0 beautifulsoup4>=4.11.0 trafilatura>=1.4.0 pyyaml>=6.0 lxml>=4.9.0 ``` The documented installation command installs these unconstrained future versions: ```bash pip install -r requirements.txt ``` ### Technical Analysis Every dependency specifies only a minimum version. Package resolution can therefore select any later version available at installation time, including releases that did not exist when the Skill was audited. This makes installations non-reproducible and expands the trusted supply-chain surface. A compromised maintainer account, malicious future release, or dependency-level compromise could cause a user to install code that was never reviewed with this Skill. Python packages can execute code during installation and are imported with the privileges of the user running the Skill. The package names themselves appear legitimate, and the audit found no evidence that the currently declared dependencies are intentionally malicious. The risk arises from unrestricted future resolution rather than confirmed dependency confusion or typosquatting. ### Attack Path 1. A direct dependency, or one of its transitive dependencies, publishes a compromised future release that still satisfies the lower-bound constraint. 2. A user follows the documented `pip install -r requirements.txt` installation procedure. 3. The resolver selects the compromised release because no exact version or integrity hash is required. 4. Malicious package behavior executes during installation or when the package is imported by the Skill. 5. The package operates with the filesystem, environment, and network permissions of the user running the installation or Skill. ### Impact Assessment A compromised dependency could potentially ...[truncated 539 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to a reviewed exact version using `==`. 2. Generate a lock file that includes all transitive dependencies. 3. Require cryptographic hashes during installation, for example through a hash-locked requirements file and `pip install --require-hashes`. 4. Build dependency updates in a controlled CI process and review security advisories and release changes before updating the lock file. 5. Use a trusted package index or an internally controlled mirror. 6. Run dependency vulnerability and provenance checks as part of release preparation. 7. Install and run the Skill in an isolated virtual environment under a non-privileged account. 8. Avoid the documented `--break-system-packages` installation approach because it can alter the system Python environment and increase the effect of dependency compromise. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
This is another documentation-to-behavior inconsistency affecting summary generation, fetching, scheduling, config handling, retry logic, and deduplication claims. Even if not directly exploitable as code execution, misleading operational claims can cause unsafe deployment decisions and conceal missing safeguards that users assume are present.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
This is another documentation-to-behavior inconsistency affecting summary generation, fetching, scheduling, config handling, retry logic, and deduplication claims. Even if not directly exploitable as code execution, misleading operational claims can cause unsafe deployment decisions and conceal missing safeguards that users assume are present.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill advertises behavior that requires network, filesystem, and environment access, but it does not declare any explicit tool scope or permissions boundary. This weakens reviewability and least-privilege controls, making it easier for a user or platform to install a skill without clearly understanding the access it needs.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
A skill that may automatically create a scheduled job and post into the current conversation changes user state and can generate ongoing outbound content without a strong up-front warning. Lack of prominent consent language increases the risk of surprise actions, spammy behavior, and inadvertent disclosure into an active chat context.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
The skill states that full original news content and generated messages are stored locally, but it does not present this as a clear data-retention warning. Users may not realize article content, logs, and output artifacts persist on disk, which increases privacy, storage, and local data exposure risk.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This shell script presents all visible status messages and usage guidance in Chinese, including the manual push instruction and scheduling note. That creates a language-policy concern because the skill forces a specific language for all users with no opt-in, fallback, or documented region-specific justification.

Missing User Warnings

Medium
Confidence
83% confidence
Finding
The code loads Telegram and Discord credentials from environment variables, which is a sensitive operation under the warning criteria for code files. Although the behavior is implemented clearly, there is no confirmation prompt or explicit user-facing warning/comment that the skill accesses these credentials for outbound integrations.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The message-generation logic explicitly produces Chinese summaries and automatically translates English titles into Chinese. This is a natural-language policy concern because the skill enforces a specific language/locale rather than offering the user a language choice or documenting an opt-in.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The module docstring at L003 states the skill generates a 200-250 character Chinese summary, and the generate_summary docstring repeats that claim at L020-L026. However, the actual length enforcement in adjust_length targets 400-500 Chinese characters, including padding short summaries with boilerplate text at L098-L119 and truncating to 500 characters at L125-L141.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The module description states that it generates a 200-250 character Chinese summary and automatically translates English content, and the implementation consistently converts English input to Chinese output. This imposes a specific language/locale behavior without presenting any user choice or documented opt-in.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
English article titles and up to 1000 characters of content are sent to translate_text, which may invoke an external translation service, without any disclosure, consent, or data-handling boundary in this code. If feeds contain licensed, sensitive, embargoed, or user-supplied content, this can leak text to third parties and create privacy, compliance, or contractual exposure.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The inline comment at L053 says the summary length is controlled to 200-250 characters, but the subsequent call adjust_length(summary, 200, 250) is misleading because the callee ignores those parameters and instead enforces a 400-500 Chinese character range via hardcoded thresholds at L098-L139. This is an active contradiction between code comments/API shape and actual behavior.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The manifest describes producing 400-500 character Chinese summaries, but generate_summary passes 200 and 250 as the requested bounds at L054, while extract_summary also targets a shorter summary in its documentation at L059-L065. Although the final enforcement logic happens to use 400-500 Chinese characters, the surrounding implementation intent is internally inconsistent with the advertised behavior, indicating a description-to-behavior mismatch in the summarization feature.

Context-Inappropriate Capability

Medium
Confidence
85% confidence
Finding
The translator silently reads API credentials from environment variables, expanding its access to secrets beyond the manifest's stated external-config behavior. In an agent/runtime environment, this can cause the skill to use ambient credentials without explicit operator intent, increasing the blast radius if the skill is installed broadly or if unexpected environment secrets are present.

External Transmission

Medium
Category
Data Exfiltration
Content
self.baidu_url = 'https://fanyi-api.baidu.com/api/trans/vip/translate'
        
        # MyMemory API (免费)
        self.mymemory_url = 'https://api.mymemory.translated.net/get'
        
        # DeepL API
        self.deepl_url = 'https://api-free.deepl.com/v2/translate'
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The module transmits supplied text to the MyMemory translation service without any user-facing disclosure or consent mechanism. Because the text may contain article content, prompts, or other sensitive data, this creates a privacy and data-governance risk, especially in an automated news aggregation skill that may process externally sourced or operator-provided content.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The Baidu translation path sends text plus authenticated request metadata to an external service without explicit disclosure. Auth-backed transmission can expose both content and service usage under the operator's account, which is more sensitive in a scheduled automation skill that may run unattended.

External Transmission

Medium
Category
Data Exfiltration
Content
'target_lang': target_lang
        }
        
        resp = requests.post(self.deepl_url, headers=headers, json=data, timeout=10)
        resp.raise_for_status()
        result = resp.json()
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The DeepL path posts text to a third-party API using an authentication key, but the skill provides no explicit user disclosure about this outbound data flow. In the context of automatic daily processing, that can result in unnoticed transfer of potentially sensitive or copyrighted text to an external processor.

Tainted flow: 'data' from requests.get (line 85, network input) → requests.post (network output)

Medium
Category
Data Flow
Content
'target_lang': target_lang
        }
        
        resp = requests.post(self.deepl_url, headers=headers, json=data, timeout=10)
        resp.raise_for_status()
        result = resp.json()
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
This YAML file contains user-facing natural-language comments entirely in Chinese, including operational guidance such as configuration instructions and option descriptions. Under the language/locale policy rule, forcing a specific language without opt-in or documented regional justification can be a policy violation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
feedparser>=6.0.0
beautifulsoup4>=4.11.0
trafilatura>=1.4.0
Confidence
96% confidence
Finding
The dependency specification uses a lower-bound range instead of pinning an exact version, which makes builds non-reproducible and can silently pull in vulnerable or breaking releases over time. In a scheduled news aggregation skill that automatically fetches remote content daily, dependency drift increases supply-chain risk and makes it hard to verify what code is actually running.

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
91% confidence
Finding
The manifest does not pin requests, and the package has multiple known advisories across versions, so it is impossible to determine from this file whether deployment will select a safe release. Because the skill performs automated outbound fetching from external sources, an affected requests version could expose credential leakage, TLS/verification, redirect, or other HTTP-client issues depending on runtime behavior.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
feedparser>=6.0.0
beautifulsoup4>=4.11.0
trafilatura>=1.4.0
pyyaml>=6.0
Confidence
95% confidence
Finding
Using feedparser>=6.0.0 allows installation of any newer version, so the deployed package may differ across environments and time. Because this skill ingests untrusted RSS/Atom feeds from external sources, unpinned parsing libraries raise supply-chain and parser-risk exposure if a compromised or vulnerable release is resolved.

Unverifiable Dependency: feedparser has 10 known advisory(ies) (CVE-2011-1157 (feedparser Cross-site Scripting vulnerability); CVE-2009-5065 (feedparser Cross-site Scripting vulnerability); CVE-2011-1158 (feedparser Cross-site Scripting vulnerability) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding
feedparser has known advisories, but the unpinned requirement prevents verification that a safe version will be installed. Since this skill consumes untrusted syndicated content directly from the internet, parser vulnerabilities are more relevant than in a purely local-use package and may affect downstream rendering or processing.

Static analysis

No suspicious patterns detected.