Back to skill

Security audit

Daily Weather News

Security checks for vulnerabilities and agentic risk

Overview

The skill’s weather/news Feishu automation is coherent, but it ships a hardcoded Tavily API key and runs an unpinned external script with that credential, so it needs review before use.

Do not run this skill as-is. Remove the embedded Tavily key from every script and document, rotate that key, supply your own secret through a controlled runtime environment instead of shell startup files, verify or vendor the Tavily search dependency, and confirm the Feishu target before enabling cron.

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/debug_news.sh:6
Finding
Hardcoded Tavily API credential exposed in executable scripts and documentation<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/debug_news.sh:6-10` - `scripts/simple_news_test.sh:6-11` - `SKILL.md:27-31` - `config/config.sh:7-13` - `references/workflow.md:72-80` **Vulnerability Type**: Hardcoded secret and plaintext credential exposure **Risk Level**: High ### Vulnerable Code From `scripts/debug_news.sh`: ```bash # Set the API key export TAVILY_API_KEY="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" # Retrieve news news_result=$(node ~/.openclaw/workspace/skills/tavily-search/scripts/search.mjs "site:news.cn 今日国际 OR site:xinhuanet.com 今日要闻 OR site:people.com.cn 国际新闻 $(date +%Y-%m-%d)" -n 6 --topic news --days 1) ``` The same credential is assigned in `scripts/simple_news_test.sh`: ```bash export TAVILY_API_KEY="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" ``` It is also disclosed through configuration examples in `SKILL.md`, `config/config.sh`, and `references/workflow.md`. ### Technical Analysis A credential-shaped Tavily API key is embedded directly in the distributed project. The two test scripts do not merely show it as an example: they export it into the process environment and use it when invoking the Tavily search implementation. Secrets committed to project files must be considered compromised because they can be recovered from distributed packages, backups, caches, logs, repository history, and forks. Removing the current visible copies alone would not invalidate copies already obtained by third parties. Environment variables are appropriate only when they are populated at deployment or execution time. Hardcoding the value before exporting it does not provide secret isolation. ### Attack Path 1. An attacker downloads the Skill package or obtains access to any repository copy, artifact, backup, or fork. 2. The attacker searches the files for `TAVILY_API_KEY` or strings beginning with `tvly-`. 3. The attacker extracts the embedded credential. 4. The attacker submits Tavily req ...[truncated 969 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Revoke the exposed Tavily key immediately and create a replacement. Rotation is required even if the current key appears unused. 2. Remove the real key from every executable script, configuration example, and documentation file. 3. Purge the credential from version-control history, release artifacts, caches, and published packages where feasible. 4. Require runtime secret injection: ```bash : "${TAVILY_API_KEY:?TAVILY_API_KEY must be supplied through the runtime environment}" export TAVILY_API_KEY ``` 5. Store the replacement in a secret manager or another access-controlled runtime facility rather than `.bashrc`, source files, or project-local configuration. 6. Replace documentation values with an unambiguously nonfunctional placeholder such as: ```bash export TAVILY_API_KEY="<set-through-secret-manager>" ``` 7. Add secret scanning to pre-commit and CI pipelines, including detection rules for Tavily key prefixes. 8. Restrict and monitor the replacement credential where the provider supports quotas, usage alerts, expiration, or scope controls. 9. Review Tavily usage logs for unauthorized requests made with the exposed credential. ]]>

T08 · Insecure Dependencies

Error
Location
scripts/daily_push.sh:108
Finding
Unpinned external JavaScript dependency executes with access to the API credential<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/daily_push.sh:108-111` - `scripts/daily_push_backup_final.sh:108-111` - `scripts/debug_news.sh:7-10` - `scripts/simple_news_test.sh:7-11` **Vulnerability Type**: Unverified executable dependency loaded from a user-writable path **Risk Level**: High ### Vulnerable Code From `scripts/daily_push.sh`: ```bash # Set the API key export TAVILY_API_KEY="$TAVILY_API_KEY" # Retrieve today's latest Chinese international news news_result=$(node ~/.openclaw/workspace/skills/tavily-search/scripts/search.mjs "site:news.cn 今日国际 OR site:xinhuanet.com 今日要闻 OR site:people.com.cn 国际新闻 $(date +%Y-%m-%d)" -n 10 --topic news --days 1) ``` The backup and test scripts invoke the same external path: ```bash node ~/.openclaw/workspace/skills/tavily-search/scripts/search.mjs ``` ### Technical Analysis The project delegates news retrieval to `search.mjs`, but that file is not included in the audited package. It is loaded by absolute expansion from the current user's home directory and is neither version-pinned nor integrity-checked. The dependency executes as JavaScript through Node.js with the same operating-system identity and environment as the parent script. Because `TAVILY_API_KEY` is exported before execution, the external code can read it directly from `process.env`. It can also perform any operation allowed to the invoking user, including reading user-accessible files, making outbound network connections, modifying user-owned files, or invoking locally available commands. A home-directory Skill installation is commonly writable by the account running the job. Consequently, compromise or replacement of the separately installed `tavily-search` Skill converts a legitimate daily cron execution into repeated execution of attacker-controlled code. The current audit did not inspect `search.mjs`, so it cannot establish that the dependency is malicious; the vulnerability is the absence of source pinning, provenance va ...[truncated 2295 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer a direct, documented HTTPS request to the Tavily API from this Skill instead of executing code from another mutable Skill directory. 2. If the external component remains necessary, pin it to a reviewed version or immutable commit and record its expected provenance. 3. Verify the dependency before every execution using a cryptographic hash or signed release. Fail closed when verification fails. 4. Install the dependency in a location that is not writable by less-trusted processes or accounts. Apply restrictive ownership and permissions. 5. Vendor the reviewed dependency into the package when licensing and maintenance requirements allow, so its effective implementation is included in future audits. 6. Use an explicit configurable dependency path and validate it with `realpath` to prevent unexpected path substitution. 7. Do not export credentials globally unless required. Pass the minimum necessary secret only to the intended process: ```bash TAVILY_API_KEY="$TAVILY_API_KEY" \ node "/verified/immutable/path/search.mjs" ... ``` 8. Run the search operation under a dedicated low-privilege account or sandbox with restricted filesystem and network access. 9. For cron deployment, use a dedicated service account, a minimal environment, absolute paths, restrictive file permissions, and documented removal instructions. 10. Monitor the dependency file for unauthorized changes and alert on hash, ownership, or permission changes. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (40)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The file presents the skill as a benign automation utility while embedding credential material and external-recipient configuration that materially affect the security posture. In security review, deceptive or incomplete behavior descriptions are dangerous because they reduce informed consent and make review/auditing harder.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The file presents the skill as a benign automation utility while embedding credential material and external-recipient configuration that materially affect the security posture. In security review, deceptive or incomplete behavior descriptions are dangerous because they reduce informed consent and make review/auditing harder.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The file presents the skill as a benign automation utility while embedding credential material and external-recipient configuration that materially affect the security posture. In security review, deceptive or incomplete behavior descriptions are dangerous because they reduce informed consent and make review/auditing harder.

Missing User Warnings

High
Confidence
98% confidence
Finding
The skill documentation not only exposes an apparently live API key but normalizes unsafe secret handling by telling users to place it into shell startup files. This creates long-lived credential exposure on disk and in shell history/configuration, increasing the blast radius if the host or dotfiles are compromised.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The documentation contains a hard-coded Tavily API key and instructs users to export it, which exposes a live credential in plain text. Anyone with access to the file can reuse the key for unauthorized API calls, incur cost, exhaust quotas, or pivot into associated services.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Content
push.sh

# 设置定时任务(每天早上7:30执行)
30 7 * * * /home/alanchan/.openclaw/workspace/skills/daily-weather-news/scripts/daily_push.sh
```

### 配置设置

**1. 设置环境变量(推荐):**
```bash
# 临时设置(当前会话有效)
export TAVILY_API_KEY="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"

# 永久设置(添加到 ~/.bashrc 或 ~/.zshrc)
echo 'export TAVILY_API_KEY="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"' >> ~/.bashrc
source ~/.bashrc
```

**2. 编辑 `config/config.sh` 文件(其他配置):**
```bash
# 目标用户ID(飞书)
TARGET_USER="ou_3a0705a4c7b5f068fff0b2b719d37978"

# 推送地点
LOCATION="黄埔"

# 日志文件路径
LOG_FILE="/home/alanchan/.openclaw/workspace/daily_push.log"
```

## 核心功能

### 1. 天气信息获取
- 使用 Open-Meteo API 获取指定地点的精确天气信息
- 通过经纬度坐标(广州:23.1291, 113.2644)精确定位
- 自动将天气代码转换�
Confidence
95% confidence
Finding
The instruction to append an exported API key into `~/.bashrc` establishes persistence of a sensitive secret on the host. While not a malware backdoor in the classic sense, it is dangerous because it creates durable credential exposure, broadens who/what can access the key in future sessions, and can leak through backups, dotfile sync, or local compromise.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Content
�改以下配置

# 推送目标用户ID (飞书用户ID)
TARGET_USER="ou_3a0705a4c7b5f068fff0b2b719d37978"

# 推送地点 (用于天气查询)
LOCATION="广州市黄埔区"

# Tavily API密钥 (用于新闻搜索)
# 请使用环境变量 TAVILY_API_KEY 设置,例如:
# export TAVILY_API_KEY="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"
# 或添加到 ~/.bashrc 或 ~/.zshrc:
# echo 'export TAVILY_API_KEY="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"' >> ~/.bashrc
# source ~/.bashrc
TAVILY_API_KEY="${TAVILY_API_KEY:-}"

# 日志文件路径
LOG_FILE="/home/alanchan/.openclaw/workspace/daily_push.log"

# 推送时间配置 (cron格式)
# 默认为每天早上7:30
CRON_TIME="30 7 * * *"

# 天气API配置
WEATHER_API_BASE="https://api.open-meteo.com/v1/forecast"

# 广州市黄埔区经纬度坐标(更精确)
LATITUDE="23.1201"
LONGITUDE="113.3826"

# 新闻搜索配置 - 优化为更精准的中文国际新闻
NEWS_SOURCES="site:news.cn 国际新闻
Confidence
95% confidence
Finding
The config comments include what appears to be a real Tavily API key example and instructions to persist it into shell startup files like ~/.bashrc. Embedding a live or realistic secret in distributed config material risks credential leakage, unauthorized API use, and accidental long-term exposure through shell history, dotfiles, or source control; the persistence aspect also makes cleanup harder.

Missing User Warnings

High
Confidence
99% confidence
Finding
The document contains a real-looking Tavily API key directly embedded in example configuration. Exposed credentials can be harvested and abused for unauthorized API usage, cost incurrence, account impact, or broader compromise if reused elsewhere.

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Content
fi
    else
        # openclaw命令未找到,静默处理
        true
    fi
}

# 主函数
main() {
    # 获取配置
    source "config/config.sh"
    
    # 检查TAVILY_API_KEY是否设置
    if [ -z "$TAVILY_API_KEY" ]; then
        echo "❌ 错误: TAVILY_API_KEY 环境变量未设置" >&2
        echo "请设置环境变量: export TAVILY_API_KEY=\"your-api-key\"" >&2
        echo "或添加到 ~/.bashrc: echo 'export TAVILY_API_KEY=\"your-api-key\"' >> ~/.bashrc" >&2
        exit 1
    fi
    
    # 获取天气信息
    weather_info=$(get_weather "$LOCATION")
    if [ -z "$weather_info" ]; then
        exit 1
    fi
    
    # 获取新闻信息
    news_info=$(get_news)
    if [ -z "$news_info" ]; then
        exit 1
    fi
    
    # 生成穿衣建议
    clothing_advice=$(get_clothing_advice "$weather_info")
    
    # 生成推送内容
    # 处理新闻信息中的转义字符
    news_display=$(echo "$news_info" | sed 's/\\n/\n/g')
    
    push_content=
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The script hardcodes and exports a live-looking Tavily API key directly in source, which is a genuine secret exposure. Anyone with access to the repository, logs, or copied script can reuse the credential for unauthorized API calls, incur cost, and potentially pivot into related integrations; in a debug script this is especially risky because such files are often less controlled and more likely to be shared.

Missing User Warnings

High
Confidence
99% confidence
Finding
Exporting a hardcoded API credential makes the secret available to the current shell environment and potentially to child processes, increasing accidental leakage through process inspection, logs, or downstream tooling. Because the key is embedded without any warning or controls, this is a clear insecure secret-handling issue rather than a false positive.

Missing User Warnings

High
Confidence
99% confidence
Finding
A hardcoded credential is not only present but actively exported and used in a networked command, meaning any execution of the script operationalizes the exposed secret. This increases the risk of credential leakage through process environments, logs, shell history, child processes, or unauthorized reuse by anyone who obtains the file.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
The description explicitly specifies Chinese international news search and Chinese output, but the documentation does not present this as optional or explain a region-specific requirement. That creates a natural-language locale constraint without user opt-in.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The documentation describes pushing collected content to Feishu but does not clearly warn users that information will be transmitted to an external recipient identifier. In an automation context, undisclosed outbound messaging can lead to accidental data leakage or messages being sent to the wrong party.

External Transmission

Medium
Category
Data Exfiltration
Content
CRON_TIME="30 7 * * *"

# 天气API配置
WEATHER_API_BASE="https://api.open-meteo.com/v1/forecast"

# 广州市黄埔区经纬度坐标(更精确)
LATITUDE="23.1201"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
CRON_TIME="30 7 * * *"

# 天气API配置
WEATHER_API_BASE="https://api.open-meteo.com/v1/forecast"

# 广州市黄埔区经纬度坐标(更精确)
LATITUDE="23.1201"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
CRON_TIME="30 7 * * *"

# 天气API配置
WEATHER_API_BASE="https://api.open-meteo.com/v1/forecast"

# 广州市黄埔区经纬度坐标(更精确)
LATITUDE="23.1201"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
CRON_TIME="30 7 * * *"

# 天气API配置
WEATHER_API_BASE="https://api.open-meteo.com/v1/forecast"

# 广州市黄埔区经纬度坐标(更精确)
LATITUDE="23.1201"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
CRON_TIME="30 7 * * *"

# 天气API配置
WEATHER_API_BASE="https://api.open-meteo.com/v1/forecast"

# 广州市黄埔区经纬度坐标(更精确)
LATITUDE="23.1201"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
CRON_TIME="30 7 * * *"

# 天气API配置
WEATHER_API_BASE="https://api.open-meteo.com/v1/forecast"

# 广州市黄埔区经纬度坐标(更精确)
LATITUDE="23.1201"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
CRON_TIME="30 7 * * *"

# 天气API配置
WEATHER_API_BASE="https://api.open-meteo.com/v1/forecast"

# 广州市黄埔区经纬度坐标(更精确)
LATITUDE="23.1201"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The comments and news query explicitly optimize the skill for Chinese-language international news, including Chinese-only sources and the term "中文." This indicates a fixed language/locale behavior without offering the user a choice or documenting an opt-in, which matches the policy category for locale/language constraints.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The skill advertises use of external weather, search, and message-push services but does not present a clear privacy or safety notice about what data is transmitted off-device and to whom. This is dangerous because users may unknowingly expose location, user identifiers, or message content to third parties.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The configuration instructions tell users to place credentials in a shell config file without warning about secure storage, file permissions, or secret rotation. This can lead to accidental exposure through version control, shared workspaces, shell history, or permissive file access.