Back to skill

Security audit

Apollo Endo

Security checks for vulnerabilities and agentic risk

Overview

The skill is not overtly malicious, but it can persistently tune global agent behavior and inspect cross-skill activity with broad triggers and weak controls.

Install only if you want a skill that may influence global agent behavior across tasks. Review and narrow its triggers, require explicit confirmation before persistent parameter changes, and avoid running the script with broad access to OpenClaw memory or other skills' private state.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/endo/endo-check.sh:13
Finding
Direct Access to Agent Memory and Cross-Skill State<![CDATA[ ## Vulnerability Details **File Location**: `scripts/endo/endo-check.sh`, lines 13–43 **Vulnerability Type**: Direct access to persistent Agent data outside a narrowly scoped telemetry interface **Risk Level**: Medium ### Complete Code Snippet ```bash # 获取当前token使用率(估算) get_token_usage() { local memory_file="/root/.openclaw/workspace/memory/$(date +%Y-%m-%d).md" if [ -f "$memory_file" ]; then local chars=$(wc -c < "$memory_file") local estimated=$((chars * 2)) # 粗略估算 echo $estimated else echo 0 fi } # 获取活跃任务数 get_active_tasks() { local task_file="/root/.openclaw/workspace/.dream/task-state.json" if [ -f "$task_file" ]; then local count=$(grep -c '"status":"active"' "$task_file" 2>/dev/null) [ -z "$count" ] && count=0 echo $count else echo 0 fi } # 获取对话轮数 get_turn_count() { local memory_file="/root/.openclaw/workspace/memory/$(date +%Y-%m-%d).md" if [ -f "$memory_file" ]; then grep -c "^## " "$memory_file" 2>/dev/null || echo 0 else echo 0 fi } ``` ### Technical Analysis The script directly opens the Agent's daily persistent memory file and another Skill's task-state file. Although the current implementation only calculates file-size, heading-count, and active-task metrics, it crosses component boundaries instead of using a dedicated, least-privilege telemetry interface. The hard-coded `/root/.openclaw/workspace` paths also assume execution in a privileged account's workspace. If the Skill is invoked with access to that workspace, it can inspect metadata derived from persistent Agent activity and from another Skill's state. The current code does not transmit the underlying contents and does not provide a direct mechanism for obtaining additional operating-system privileges. ### Attack Path 1. The Skill is invoked in an environment where it can read `/root/.openclaw/workspace`. 2. `get_token_usage` opens the current da ...[truncated 1234 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace direct memory-file access with a dedicated telemetry interface that returns only approved aggregate values. 2. Store task metrics in an Endo-specific input file rather than scanning another Skill's private state. 3. Require explicit authorization before inspecting persistent Agent memory or cross-Skill state. 4. Apply filesystem permissions that restrict each Skill to its own state directory. 5. Avoid hard-coded `/root` paths. Resolve an explicitly configured, nonprivileged workspace and validate it before use. 6. Run the Skill under a dedicated unprivileged account with access only to the telemetry and state files required for its function. 7. Document every cross-Skill data dependency and define a stable schema containing no conversation content or unnecessary metadata. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/endo/endo-check.sh:5
Finding
Predictable State-File Overwrite Without Symlink Protection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/endo/endo-check.sh`, lines 5–6 and 105–114 **Vulnerability Type**: Unsafe write to a predictable path **Risk Level**: Low ### Complete Code Snippet ```bash STATE_FILE="/root/.openclaw/workspace/.endo/state.json" mkdir -p "$(dirname "$STATE_FILE")" ``` ```bash # 保存状态 cat > "$STATE_FILE" << EOF { "tokens": $tokens, "active_tasks": $tasks, "turn_count": $turns, "load": $load, "adjustment": "$adjustment", "checked_at": "$(date -Iseconds)" } EOF ``` ### Technical Analysis The script writes generated JSON to a fixed, predictable path using shell redirection. The operation truncates the destination before writing and does not verify whether `state.json` is a regular file, whether it is a symbolic link, or whether the parent directory has safe ownership and permissions. If a less-privileged attacker can modify the `.endo` directory or replace `state.json` with a symbolic link, and the script later executes with greater filesystem privileges, shell redirection follows the symbolic link and overwrites its target. This is a conditional privilege-boundary issue: it requires attacker write access to the state directory and a more privileged invocation of the script. The replacement content is constrained to the generated JSON document, so the attacker cannot freely select arbitrary content. Nevertheless, truncating and replacing a chosen writable target may corrupt configuration or application-state files. ### Attack Path 1. An attacker obtains write access to `/root/.openclaw/workspace/.endo`, or to an equivalent state directory in a deployment with unsafe permissions. 2. The attacker removes or renames `state.json`. 3. The attacker creates `state.json` as a symbolic link to a file writable by the account that will execute the Skill. 4. A more privileged user or service invokes `endo-check.sh`. 5. The shell processes `cat > "$STATE_FILE"` and follows the symbolic link. 6. The lin ...[truncated 878 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Ensure the state directory is owned by the dedicated execution account and is not writable by group members or other users. A restrictive mode such as `0700` is appropriate for private state. 2. Reject an existing symbolic-link destination before writing, but do not rely on a separate check alone because it can introduce a time-of-check/time-of-use race. 3. Create a temporary file securely inside the trusted state directory using `mktemp`. 4. Set a restrictive `umask`, such as `077`, before creating state files. 5. Write the JSON to the temporary regular file, verify successful completion, and atomically rename it over the destination. 6. Use APIs or utilities that support no-follow semantics, such as `openat` with `O_NOFOLLOW`, where available. 7. Verify the ownership and type of the parent directory before each write. 8. Avoid running the script as root. Use a dedicated unprivileged account limited to its own state directory. 9. Add error handling so failed directory creation, temporary-file creation, writes, and renames terminate without leaving partial state. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Vague Triggers

Medium
Confidence
97% confidence
Finding
The manifest's read_when conditions are broad natural-language concepts like '参数', '设置', and '调整', which are likely to appear in ordinary conversation. This can cause unintended activation of the skill, allowing it to influence global behavior or user experience outside its intended scope.

Vague Triggers

Medium
Confidence
98% confidence
Finding
The trigger list contains highly generic keywords including '参数', '偏好', '设置', '调整', and '系统状态', all of which can occur in many benign requests. In a skill designed to tune global parameters, accidental invocation is more dangerous because it may change broad system behavior rather than a single task-local setting.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documented workflow includes writing a parameter state file and notifying other skills that new parameters are active, but it provides no safeguards, user warning, audit trail, or rollback mechanism. Because these are global parameters affecting other skills, persisted state changes can silently alter future behavior across the system and amplify the effect of accidental or malicious activation.

Static analysis

No suspicious patterns detected.