Back to skill

Security audit

aiinsight-daily-new

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated AI news digest purpose, but its fetch script can run crafted code and may expose webhook tokens in logs, so it needs Review before installation.

Install only if you trust the publisher and can harden the script first. At minimum, pass values to Python as arguments or environment data using a quoted heredoc, validate count and RSS URL, avoid logging webhook URL paths or tokens, and use webhooks only for destinations you control.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch.sh:19
Finding
Arbitrary Python Code Execution Through Shell-Expanded Heredoc Inputs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch.sh`, lines 19-24 **Vulnerability Type**: Python code injection through an unquoted shell heredoc **Risk Level**: High ### Vulnerable Code ```bash # Python 解析 RSS 并输出 python3 << EOF import feedparser import urllib.request import os import json import re url = "$RSS_URL" count = int("$COUNT") ``` ### Technical Analysis The script uses an unquoted heredoc delimiter (`<< EOF`). Consequently, the shell expands `$RSS_URL` and `$COUNT` before passing the heredoc body to Python. Both values are inserted directly into Python source-code contexts: - `RSS_URL` is controllable through the `AI_DAILY_RSS_URL` environment variable. - `COUNT` is controllable through the script's first positional argument or the `AI_DAILY_DEFAULT_COUNT` environment variable. Because these values are not passed as data through `sys.argv` or the process environment, an attacker can terminate the surrounding Python syntax and append arbitrary Python statements. For example, a malicious count argument could be constructed in the following form: ```text 1"); __import__("os").system("id"); # ``` After shell interpolation, the generated Python statement would be equivalent to: ```python count = int("1"); __import__("os").system("id"); #") ``` The injected statement is then executed by `python3`. Validation through `int()` does not prevent this attack because injection occurs at the Python source-code level before `int()` processes the value. ### Attack Path 1. An attacker gains the ability to influence the argument supplied to `scripts/fetch.sh`, `AI_DAILY_DEFAULT_COUNT`, or `AI_DAILY_RSS_URL`. 2. The attacker supplies a value that closes the generated Python string or expression and adds Python statements. 3. The unquoted heredoc expands the attacker-controlled value into the Python program. 4. The script invokes `python3` on the dynamically constructed program. 5. Python executes the injected statements with the privil ...[truncated 755 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Use a quoted heredoc so that the shell does not interpolate values into Python source code. Pass runtime values as command-line arguments or environment variables: ```bash python3 - "$RSS_URL" "$COUNT" <<'PY' import sys import urllib.parse url = sys.argv[1] try: count = int(sys.argv[2]) except ValueError: raise SystemExit("COUNT must be an integer") if not 1 <= count <= 100: raise SystemExit("COUNT must be between 1 and 100") parsed_url = urllib.parse.urlparse(url) if parsed_url.scheme != "https" or not parsed_url.hostname: raise SystemExit("RSS URL must be a valid HTTPS URL") # Remaining implementation PY ``` Additional hardening should include: 1. Validate `COUNT` in the shell or Python and enforce a reasonable positive upper bound. 2. Permit only HTTPS RSS URLs. 3. If arbitrary RSS sources are unnecessary, allowlist the documented official hostname. 4. Consider rejecting loopback, link-local, private-network, and cloud metadata destinations to reduce server-side request forgery risk when the RSS URL can be supplied by untrusted users. 5. Run the Skill as an unprivileged account with access only to resources needed for RSS retrieval and webhook delivery. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch.sh:121
Finding
Webhook Credentials May Be Disclosed Through Console and Log Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch.sh`, lines 121-126 **Vulnerability Type**: Sensitive information exposure through logging **Risk Level**: Medium ### Vulnerable Code ```python req = urllib.request.Request(wh, data.encode('utf-8'), headers) with urllib.request.urlopen(req, timeout=10) as f: resp = f.read().decode('utf-8') print(f"✅ 推送成功: {wh[:60]}...") except Exception as e: print(f"❌ 推送失败: {wh[:60]}...\n Error: {e}") ``` ### Technical Analysis Webhook URLs frequently contain credentials or bearer-like secrets in their path or query string. Examples include Bark device keys and bot webhook access tokens. The script prints the first 60 characters of every configured webhook URL on both successful and failed delivery attempts. Truncating a URL to 60 characters is not a reliable redaction mechanism. A complete token may appear within that prefix, and even a partial token may expose sensitive identifying material. Output from Skills may be retained in terminal captures, automation logs, CI records, monitoring platforms, or agent transcripts that are accessible to more users than the original webhook configuration. The failure path additionally prints the exception text. Depending on the exception generated by the networking library, this text may contain request or destination details and should not be treated as safe for unrestricted logging. ### Attack Path 1. A user configures `AI_DAILY_WEBHOOKS` with one or more token-bearing webhook URLs. 2. The Skill attempts to deliver the generated digest. 3. On either success or failure, the script prints the first 60 characters of the webhook URL. 4. The output is captured by a shell history mechanism, agent transcript, job log, or centralized monitoring system. 5. A person or service with access to those logs recovers the complete token or a sensitive token fragment. 6. If the disclosed value is sufficient ...[truncated 812 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not print webhook paths, query strings, fragments, or token-bearing URL prefixes. Parse the URL and log only a validated hostname and a non-sensitive channel label: ```python from urllib.parse import urlsplit def safe_webhook_name(webhook): parsed = urlsplit(webhook) return parsed.hostname or "invalid-webhook" # After delivery: print(f"Webhook delivery succeeded: {safe_webhook_name(wh)}") # On failure: print(f"Webhook delivery failed: {safe_webhook_name(wh)}") ``` Further hardening should include: 1. Avoid logging raw exception representations when they may contain URLs. Map exceptions to short, sanitized error categories. 2. Store webhook URLs in a secret-management facility where available. 3. Restrict access to process environments and execution logs. 4. Rotate any webhook token that may already have appeared in logs. 5. Add automated tests verifying that output never contains webhook paths, query parameters, or known token values. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill explicitly supports pushing fetched content to multiple webhooks, but the description does not clearly warn that retrieved content may be transmitted to external endpoints. This creates a transparency and data-handling risk because users may invoke the skill for local retrieval without realizing the content could be forwarded outside the system.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger phrases are quite broad and generic for AI/news-related conversation, which increases the chance the skill is invoked unintentionally in contexts where the user did not mean to fetch or distribute content. While this is not directly exploitable like code execution, accidental invocation can lead to unwanted network access or downstream webhook pushes if the skill is wired to auto-send results.

External Transmission

Medium
Category
Data Exfiltration
Content
```bash
# 多个推送渠道,空格分隔。支持:Bark / 企业微信机器人 / 飞书机器人 / 钉钉机器人 / 通用 webhook
export AI_DAILY_WEBHOOKS="https://api.day.app/your-token https://other-webhook"

# 默认获取最新条数
export AI_DAILY_DEFAULT_COUNT=1
Confidence
90% confidence
Finding
The documented configuration includes external webhook URLs, confirming that the skill can transmit content to third-party services. In this context the transmission is an intended feature, but it still presents a real security concern because webhook destinations are externally controlled and could receive data without sufficient validation, user awareness, or destination restrictions.

External Transmission

Medium
Category
Data Exfiltration
Content
# AI Daily 配置

# 多个推送渠道,空格分隔
# export AI_DAILY_WEBHOOKS="https://api.day.app/your-token https://other-webhook"

# 默认获取最新条数(通常 1 条就是今日日报)
# export AI_DAILY_DEFAULT_COUNT=1
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The script header claims it only fetches RSS content, but later code also transmits the fetched content to arbitrary webhook URLs from the environment. This creates a transparency and trust problem: operators may run the script expecting local output only, while it can exfiltrate content to external services without clear disclosure.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script sends fetched content to externally configured webhooks with no user-facing warning, confirmation, or dry-run mode. In an agent skill context, silent outbound transmission increases the risk of unintended data disclosure or misuse of trusted automation to post content to third-party endpoints.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
Comments and printed output strings are consistently in Chinese, including status messages and generated report titles, which effectively fixes the user experience to a specific language. The file does not offer user opt-in for language selection or explain that the skill is intentionally limited to a Chinese-speaking context.

Static analysis

No suspicious patterns detected.