Back to skill

Security audit

Apollo Neuro

Security checks for vulnerabilities and agentic risk

Overview

This skill is review-worthy because it broadly changes task-handling behavior, can reduce confirmations and validation, and stores raw task text without clear controls.

Install only if you want this skill to influence the agent's routing policy. Keep it away from workflows that send messages, modify files, publish content, spend money, or handle secrets unless confirmations and full validation remain enforced outside the skill. Treat the /root/.openclaw/workspace/.neuro/route-state.json file as potentially sensitive because it can contain raw task text.

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
scripts/neuro/neuro-check.sh:163
Finding
Unescaped User-Controlled Data Written to Persistent JSON State## Vulnerability Details **File Location**: `scripts/neuro/neuro-check.sh`, lines 163–172 **Vulnerability Type**: JSON injection and persistent state corruption **Risk Level**: Medium ### Vulnerable Code ```bash cat > "$STATE_FILE" << EOF { "task": "$task", "task_type": "$task_type", "route": "$final_route", "circadian": "$circadian", "is_efficient": $is_efficient, "decided_at": "$(date -Iseconds)" } EOF ``` ### Technical Analysis The script directly interpolates user-controlled task text into a JSON document without applying JSON string escaping. The task originates from the first command-line argument: ```bash local task="${1:-}" ``` Consequently, double quotes, backslashes, control characters, and newlines in the task can terminate or alter the intended JSON string. An attacker can produce malformed JSON or inject additional object properties. The value of `circadian` is also interpolated without escaping after being read from a separate persistent state file. The generated content is stored at the fixed path `/root/.openclaw/workspace/.neuro/route-state.json`. Because this is persistent shared state, downstream workspace components may consume corrupted or attacker-influenced routing information. This is data-format injection rather than shell command injection: the here-document performs parameter expansion, but shell syntax contained inside an expanded variable is not reparsed as executable shell code. ### Attack Path 1. An attacker supplies a crafted task containing JSON syntax, such as: ```text x", "route": "attacker-controlled", "injected": "true ``` 2. `main` accepts the entire value as `task`, and the classification functions process it as ordinary text. 3. The here-document inserts the value directly between JSON quotation marks without serialization or escaping. 4. The resulting `route-state.json` is malformed or contains attacker-influenced properties. 5. A downstream component that reads and trusts thi ...[truncated 934 chars]
Remediation
## Remediation Suggestions 1. Generate the state file with a genuine JSON serializer rather than a shell here-document. For example, pass each value to Python and use `json.dump`: ```bash python3 - "$STATE_FILE" "$task" "$task_type" "$final_route" \ "$circadian" "$is_efficient" "$(date -Iseconds)" <<'PY' import json import os import sys import tempfile destination, task, task_type, route, circadian, efficient, decided_at = sys.argv[1:] state = { "task": task, "task_type": task_type, "route": route, "circadian": circadian, "is_efficient": int(efficient), "decided_at": decided_at, } directory = os.path.dirname(destination) fd, temporary = tempfile.mkstemp(dir=directory, prefix=".route-state-", text=True) try: with os.fdopen(fd, "w", encoding="utf-8") as stream: json.dump(state, stream, ensure_ascii=False) stream.write("\n") stream.flush() os.fsync(stream.fileno()) os.chmod(temporary, 0o600) os.replace(temporary, destination) except Exception: try: os.unlink(temporary) except FileNotFoundError: pass raise PY ``` 2. Use atomic replacement so concurrent readers never observe a partially written document. 3. Apply restrictive permissions to the state directory and file, such as directory mode `0700` and file mode `0600`. 4. Prefer a caller-scoped or application-scoped state directory over a fixed shared root-workspace path when multiple trust domains may invoke the script. 5. Validate the circadian state schema and require `name` to be a string of an acceptable length before propagating it. 6. Add regression tests with quotation marks, backslashes, newlines, Unicode characters, and duplicate-key injection payloads, then verify that the resulting file always parses to the intended object.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (9)

Vague Triggers

High
Confidence
97% confidence
Finding
The read_when triggers include very common conversational terms such as '紧急', '马上', '稍后', and '仔细想想', which can cause the skill to activate during ordinary dialogue rather than explicit routing requests. In this skill, accidental invocation is especially risky because activation can route requests into a fast path that reduces confirmation and process validation.

Vague Triggers

High
Confidence
98% confidence
Finding
The manifest trigger list is composed of generic everyday phrases with no context boundaries, making unintended invocation likely across normal conversation. Because this skill changes decision policy for execution speed and verification depth, broad triggering can silently alter the agent's safety posture without the user knowingly requesting it.

Missing User Warnings

High
Confidence
98% confidence
Finding
The skill explicitly states that the fast path should skip multiple rounds of confirmation and directly execute, which weakens an important safety control. For actions involving messaging, file handling, external side effects, or sensitive operations, reduced confirmation can lead to unauthorized, mistaken, or irreversible actions under the pretext of urgency.

Missing User Warnings

High
Confidence
97% confidence
Finding
The fast-path section reduces both confirmation and verification, stating that only the result should be checked rather than the process. This creates a substantial risk of unsafe execution, especially when malicious or ambiguous requests attempt to exploit urgency to bypass normal scrutiny.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The description and interaction model are entirely Chinese-language, and the trigger phrases and output examples assume Chinese input without mentioning user choice or a region-specific limitation. This can constitute a language/locale policy issue because the skill appears to force one language by default.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The intuition path directs the system to reuse historical solutions and 'not re-reason,' which can misapply stale or context-inappropriate actions to new inputs. In a security-sensitive or action-taking agent, pattern-based reuse without fresh validation can propagate previous mistakes or enable prompt-triggered unsafe automation.

Skill Enumeration

Medium
Category
Agent Snooping
Content
|------|------|
| scripts/neuro/neuro-classify.sh | 任务分类脚本 |
| .neuro/patterns.json | 直觉pattern存储 |
| skills/apollo-neuro/SKILL.md | 本文档 |

## v1 实施规格
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.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script persists the raw task description, routing decision, and timing/context metadata to a file under /root without any notice, consent, minimization, or retention control. Because task text may contain sensitive prompts, credentials, business data, or incident details, this creates an information disclosure risk if the file is later accessed by other tools, users, backups, or logs.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
Comments, usage text, and user-facing output strings are entirely in Chinese, including the main report and help text. Under the policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.

Static analysis

No suspicious patterns detected.