Back to skill

Security audit

openpd

Security checks for vulnerabilities and agentic risk

Overview

This skill appears aimed at automated market reports, but it needs review because it installs recurring cron jobs, sends reports through OpenClaw messaging, and handles API keys with weak local security practices.

Install only if you are comfortable with a scheduled job that runs every weekday, calls external market/news APIs, writes reports and logs locally, and sends messages through your OpenClaw messaging setup. Store API keys outside the skill source if possible, review the exact cron entries before enabling them, do not run the installer as root, and confirm the delivery channel and target user before allowing automated pushes.

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

T09 · Insecure Skill Coding Practices

Warning
Location
install_cron.py:74
Finding

Predictable Shared Temporary File Permits Symlink-Based File Overwrite

Content
View full analysis

Vulnerability Details

File Location: install_cron.py:74-79 and install_cron.py:127-131
Vulnerability Type: Predictable temporary file / symlink following
Risk Level: Medium

Vulnerable Code

The cron installation path uses a fixed filename:

python
temp_file = "/tmp/cron_temp.txt"
with open(temp_file, "w") as f:
    f.write(new_cron)

result = subprocess.run(
    ["crontab", temp_file],
    capture_output=True,
    text=True
)

The uninstallation path repeats the same unsafe pattern:

python
temp_file = "/tmp/cron_temp.txt"
with open(temp_file, "w") as f:
    f.write("\n".join(new_lines))

result = subprocess.run(
    ["crontab", temp_file],
    capture_output=True,
    text=True
)

Technical Analysis

/tmp is normally a shared, world-writable directory. The constant path /tmp/cron_temp.txt can be predicted and created before the installer runs. Python's standard open(..., "w") follows symbolic links and does not require exclusive creation.

A local attacker can therefore place a symbolic link at that path pointing to another file writable by the user who runs the installer. Opening the path truncates and replaces the linked target with generated crontab content.

The implementation also does not explicitly set mode 0600. Consequently, crontab contents may be exposed to other local users depending on the process umask. Cleanup occurs only after successful crontab execution, so exceptions and failed subprocess calls can leave the temporary file behind.

This issue affects both installation and uninstallation. It does not independently grant root privileges: the overwrite is constrained by the filesystem permissions of the account running install_cron.py. If the script is unnecessarily run under a privileged account, however, the potential scope increases to files writable by that account.

Attack Path

  1. The attacker has access to the same multi-user host and can write to /tmp.
  2. The attacker predicts ...[truncated 1612 chars]
Remediation
View remediation

Remediation Suggestions

Avoid filesystem-based transfer entirely by sending the new crontab through standard input:

python
result = subprocess.run(
    ["crontab", "-"],
    input=new_cron,
    capture_output=True,
    text=True,
    timeout=30,
    check=False,
)

Apply the same approach to uninstallation.

If a temporary file is unavoidable:

  1. Create it with Python's tempfile module using a unique, unpredictable name.
  2. Restrict its permissions to 0600.
  3. Keep it on a trusted local filesystem.
  4. Remove it in a finally block, regardless of subprocess success.
  5. Do not follow attacker-controlled symbolic links.
  6. Do not run the installer as root because it only needs to modify the current user's crontab.

Example:

python
import os
import tempfile

temp_path = None
try:
    with tempfile.NamedTemporaryFile(
        mode="w",
        encoding="utf-8",
        prefix="market-open-cron-",
        delete=False
    ) as temp_file:
        temp_path = temp_file.name
        os.chmod(temp_path, 0o600)
        temp_file.write(new_cron)

    result = subprocess.run(
        ["crontab", temp_path],
        capture_output=True,
        text=True,
        timeout=30,
        check=False,
    )
finally:
    if temp_path:
        try:
            os.unlink(temp_path)
        except FileNotFoundError:
            pass

Additionally, make cron installation explicitly opt-in, display the exact entries before installation, and document that it must be run as the intended unprivileged user.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (49)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

A second, distinct mismatch exists between the declared skill purpose and the described underlying behavior: undeclared local file writes, ambiguous message-delivery channels, misleading report field semantics, and unsupported automation/news features. These inconsistencies weaken informed consent and can hide security-relevant side effects such as persistent storage or broader-than-expected outbound communication.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

A second, distinct mismatch exists between the declared skill purpose and the described underlying behavior: undeclared local file writes, ambiguous message-delivery channels, misleading report field semantics, and unsupported automation/news features. These inconsistencies weaken informed consent and can hide security-relevant side effects such as persistent storage or broader-than-expected outbound communication.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

清单描述该技能应在固定时间收集黄金和 WTI 数据、结合隔夜新闻进行开盘预测并推送飞书;但本文件的模块说明和实际代码仅实现了 CommodityPriceAPI 的最新价、历史价和区间查询,以及本地格式化输出。代码中没有任何开盘预测、新闻分析、定时调度或飞书推送逻辑,说明声明能力与实际行为存在明显语义偏差。

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · main.py (reported line 640)May include surrounding context.

python
help="指定日期 (YYYY-MM-DD),默认为今天")
    parser.add_argument("--target", type=str, default=DEFAULT_TARGET,
                        help="推送目标用户 open_id")
    parser.add_argument("--skip-check", action="store_true",
                        help="跳过 API Key 检查")
    args = parser.parse_args()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The installation guide explicitly tells users to place API keys directly into source files, which creates a high risk of credential exposure through backups, source sharing, screenshots, logs, or accidental commits. This is not an exploit by itself, but it promotes insecure secret handling and can lead to unauthorized use of external APIs or downstream compromise of connected services.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · INSTALL.md (reported line 75)May include surrounding context.

bash
# 查看定时任务
crontab -l

# 手动测试收集
python3 ~/.openclaw/skills/market-open-analysis/main.py --stage collect

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · QUICKSTART.md (reported line 81)May include surrounding context.

bash
# 查看定时任务
crontab -l

# 手动测试收集
python3 ~/.openclaw/skills/market-open-analysis/main.py --stage collect

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · SKILL.md (reported line 212)May include surrounding context.

bash
# 查看定时任务
crontab -l

# 手动测试收集
python3 ~/.openclaw/skills/market-open-analysis/main.py --stage collect

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · SKILL.md (reported line 309)May include surrounding context.

bash
# 查看定时任务
crontab -l

# 手动测试收集
python3 ~/.openclaw/skills/market-open-analysis/main.py --stage collect

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · install_cron.py (reported line 86)May include surrounding context.

python
```bash
# 查看定时任务
crontab -l

# 手动测试收集
python3 ~/.openclaw/skills/market-open-analysis/main.py --stage collect

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · INSTALL.md (reported line 169)May include surrounding context.

Q: 如何修改推送时间?

编辑 crontab:

bash
crontab -e
# 修改时间(例如改为 6:00 和 6:30)
0 6 * * 1-5 ...
30 6 * * 1-5 ...

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · INSTALL.md (reported line 178)May include surrounding context.

Q: 如何修改推送时间?

编辑 crontab:

bash
crontab -e
# 修改时间(例如改为 6:00 和 6:30)
0 6 * * 1-5 ...
30 6 * * 1-5 ...

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · SKILL.md (reported line 215)May include surrounding context.

Q: 如何修改推送时间?

编辑 crontab:

bash
crontab -e
# 修改时间(例如改为 6:00 和 6:30)
0 6 * * 1-5 ...
30 6 * * 1-5 ...

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

Scanner excerpt · INSTALL.md (reported line 185)May include surrounding context.

Q: 如何查看历史报告?

bash
ls -la ~/openclaw/workspace/reports/
cat ~/openclaw/workspace/reports/market_open_20260317_*.md

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Content

Scanner excerpt · SKILL.md (reported line 283)May include surrounding context.

Q: 如何查看历史报告?

bash
ls -la ~/openclaw/workspace/reports/
cat ~/openclaw/workspace/reports/market_open_20260317_*.md

Skill Enumeration

Medium
Category
Agent Snooping
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.

Content

Scanner excerpt · INSTALL.md (reported line 198)May include surrounding context.

md
## 📞 技术支持

- Skill 文档:`~/.openclaw/skills/market-open-analysis/SKILL.md`
- 日志文件:`~/openclaw/workspace/logs/market_open.log`

---

Skill Enumeration

Medium
Category
Agent Snooping
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.

Content

Scanner excerpt · SKILL.md (reported line 339)May include surrounding context.

md
## 📞 技术支持

- Skill 文档:`~/.openclaw/skills/market-open-analysis/SKILL.md`
- 日志文件:`~/openclaw/workspace/logs/market_open.log`

---

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This markdown file contains user-facing instructions exclusively in Chinese, and it does not offer an alternative language or indicate that the skill is region- or locale-specific. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest describes this skill as automatically pushing the opening analysis report to Feishu, but the quickstart instructs users to configure Telegram, Discord, Slack, and WhatsApp as supported delivery channels. That is a broader operational scope than the stated skill description and changes the apparent destinations of outbound data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

该技能说明全文均为中文,包含标题、步骤、示例和注意事项,但没有说明这是面向特定中文用户群的区域性技能,也没有提供语言/locale 选择。根据规则,未经用户选择而强制单一语言属于自然语言层面的组织策略问题。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares capabilities that require file access, networking, shell execution, and persistence-oriented setup steps, but it does not declare any explicit tool scope or permission boundaries. In an agent environment, missing scope metadata can cause overbroad execution privileges and reduce a user's ability to review or constrain what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The primary description is written entirely in Chinese and presents the skill as a general-purpose market analysis skill, with no indication that the language is optional or limited to a China-specific audience. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
92% confidence
Finding

The skill instructs the user to create cron entries that will execute code automatically on a recurring basis, establishing persistence beyond the current session. Persistence is security-relevant because it causes ongoing unattended execution with network and file access, increasing the blast radius if the skill is faulty, compromised, or later modified.

Content

Scanner excerpt · SKILL.md (reported line 120)May include surrounding context.

或手动添加:

bash
crontab -e

# 添加以下两行(交易日 5:00 收集,5:30 推送)
0 5 * * 1-5 /usr/bin/python3 ~/.openclaw/skills/market-open-analysis/main.py --stage collect

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

文件顶部文档将该模块明确描述为价格查询工具,功能语义聚焦于“获取国际商品价格”;而技能清单将整体技能定位为自动生成并推送开盘预测报告。这里不是简单的信息缺失,而是代码文档主动给出了与技能宣称用途不同的实现意图。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module description and user-facing strings are written in Chinese, and the command-line interface presents prompts and output in Chinese only. This creates a language/locale constraint without any opt-in, alternative language option, or justification that the skill is intended only for a Chinese-speaking or region-specific context.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.