Back to skill

Security audit

ai news weekly agent

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated AI weekly-report purpose, but it needs review because it can fetch untrusted web URLs without destination restrictions and may forward fetched excerpts to an LLM.

Install only if you are comfortable with the skill fetching configured RSS/news sources, following article links from those feeds, sending selected report content to your configured LLM provider, and writing a local Markdown report. Use trusted sources only, avoid --allow-insecure-ssl and --allow-custom-llm-endpoint unless necessary, provide API keys through protected environment injection rather than command-line arguments, and review generated reports before sharing them.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
run_daily_digest.py:62
Finding

Unrestricted Feed and Article Fetching Enables Server-Side Request Forgery

Content
View full analysis
str: req = urllib.request.Request(url, headers={"User-Agent": USER_AGENT}) def _read_with_context(context: ssl.SSLContext) -> str: with urllib.request.urlopen(req, timeout=timeout, context=context) as resp: return resp.read().decode("utf-8", errors="ignore") try: return _read_with_context(ssl.create_default_context()) except ssl.SSLCertVerificationError: if not allow_insecure_fallback: raise return _read_with_context(ssl._create_unverified_context()) except urllib.error.URLError as ex: if not allow_insecure_fallback: raise if isinstance(ex.reason, ssl.SSLCertVerificationError): return _read_with_context(ssl._create_unverified_context()) raise ``` The configured RSS URL is passed directly to this unrestricted function: ```python for src in sources: name = src.get("name", "unknown") rss = src.get("rss_url", "").strip() category = src.get("category", "其他") if not rss: errors.append(f"{name}: rss_url empty") continue try: xml_text = fetch_text(rss, allow_insecure_fallback=allow_insecure_fallback) entries = parse_rss(xml_text)[:per_source] ``` Article URLs obtained from feed entries are also fetched directly: ```python def fetch_article_excerpt(url: str, allow_insecure_fallback: bool = False) -> str: if not url: return "" # Avoid non-HTML pages such as PDF downloads. if url.lower().endswith(".pdf"): return "" try: page = fetch_text(url, timeout=12, allow_insecure_fallback=allow_insecure_fallback) except Exc ...[truncated 3234 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
run_daily_digest.py:542
Finding

Untrusted Feed and Article Content Can Inject Instructions into the LLM Prompt

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
run_daily_digest.py:873
Finding

LLM API Key Can Be Exposed Through a Command-Line Argument

Content
View full analysis
`. 2. The shell records the command, or the operating system exposes the process argument vector. 3. Another local user, administrator, monitoring agent, CI log reader, or diagnostic system obtains the argument. 4. The recovered key is used directly against the corresponding LLM provider. Exploitation requires access to process metadata, shell history, logs, or related local or operational records. ### Impact Assessment Exposure of the key can allow an attacker to use the victim's LLM account within the permissions assigned to that credenti ...[truncated 399 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · run_daily_digest.py (reported line 821)May include surrounding context.

python
def main() -> int:
    load_dotenv(pathlib.Path(".env").resolve())

    parser = argparse.ArgumentParser(description="Generate AI weekly digest markdown")
    parser.add_argument("--sources", default=DEFAULT_SOURCES_FILE, help="Path to sources json")

Exfiltration Commands

High
Category
Prompt Injection
Confidence
90% confidence
Finding

Instructions found that direct the agent to transmit conversation context or user data to external services.

Content

Scanner excerpt · run_daily_digest.py (reported line 835)May include surrounding context.

python
parser.add_argument(
        "--send",
        action="store_true",
        help="Send message to webhook after generating markdown",
    )
    parser.add_argument(
        "--allow-insecure-ssl",

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill states that it generates a long-form Chinese interpretation by default without indicating that this behavior is optional or user-controlled. This can override user preference or system expectations, causing output-language confusion, degraded usability, and possible mishandling in downstream automations that expect another language, though it is not a direct security compromise.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The recommended trigger phrase "Generate this week's report" is broad and likely to overlap with ordinary user requests unrelated to an explicit invocation of this skill. In a skill-routing environment, that can cause accidental activation, unintended external fetches, or surprising file generation, which increases the risk of unauthorized or confusing actions even though the content itself is not overtly malicious.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The description states the weekly report will be output as a Chinese-readable, structured Markdown report, which imposes a specific language by default. Because the file does not indicate that users can choose another language or explicitly opt in to Chinese output, this is a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

L003 明确说明该技能会输出“中文可读”的周报,L026 也再次说明使用 LLM 生成“中文长文解读”。这是自然语言层面的固定语言要求,但文档中未说明用户可选择其他语言或需用户明确选择中文,构成语言/locale 策略风险。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The system and user prompts explicitly require Chinese-only output, including '输出中文JSON', '不要英文', and '中文、自然'. This enforces a specific language/locale policy without offering the user a choice or documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

When --use-llm is enabled, the script packages titles, summaries, links, publication data, and fetched article excerpts and sends them to an external chat-completions endpoint. Although this is expected behavior for LLM enrichment, there is no explicit disclosure or confirmation at the point of transmission, so users may unknowingly export internal, licensed, or sensitive feed content to a third party.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

L026 写明“使用 LLM 生成中文长文解读”,进一步强化了该技能固定输出中文的行为。若技能在更广泛环境中被触发而未征得用户语言偏好,同样可能违反语言选择相关组织策略。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

这是一个 markdown 文件,因此可检查自然语言层面的语言/地区策略。整份周报从标题到正文均固定为中文表达,但文件中没有说明该技能仅面向中文用户、也没有提供语言可选项或用户同意机制,属于未明确告知的语言固定。

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script description and generated filename/content consistently frame the output as a weekly digest (for example, 'Generate AI weekly digest markdown' and 'AI 资讯周报'), but the webhook message text says 'AI 日报已生成'. This is a direct contradiction in user-facing intent/documentation rather than a mere omission.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This JSON file contains natural-language labels in both English and Chinese, with category values consistently forced to Chinese terms such as 官方发布、开源与工具、论文研究、行业资讯, and 国内厂商动态. Because the file provides no indication that the skill is intentionally Chinese-only or that users can choose a locale, it presents a mild language/locale policy concern.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.