Back to skill

Security audit

Manus Monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly supports Manus task management, but it also installs an under-disclosed recurring OpenClaw monitor that can run every minute and send Telegram notifications.

Review before installing. Use only if you are comfortable with a saved Manus task automatically creating a recurring OpenClaw monitor, repeated Manus API polling, optional Telegram notifications, and local file downloads. Avoid using it with sensitive prompts or outputs unless you first remove or explicitly control the cron monitor and inspect downloaded files before sharing or opening them.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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 (4)

T06 · System Persistence

Error
Location
scripts/manus.sh:128
Finding
Automatic Installation of a Recurring OpenClaw Agent Task<![CDATA[ ## Vulnerability Details **File Location**: `scripts/manus.sh:128-132`; `scripts/manus-monitor-start.sh:9-30` **Vulnerability Type**: Cross-session scheduled-task persistence **Risk Level**: High ### Vulnerable Code From `scripts/manus.sh:128-132`: ```bash SCRIPT_DIR="$(dirname "$0")" if [ -f "$SCRIPT_DIR/manus-monitor-start.sh" ]; then "$SCRIPT_DIR/manus-monitor-start.sh" > /dev/null 2>&1 fi ``` Relevant persistence operations from `scripts/manus-monitor-start.sh:9-30`: ```bash if openclaw cron list 2>/dev/null | grep -q "manus-task-monitor"; then exit 0 fi openclaw cron add << EOF { "name": "manus-task-monitor", "schedule": { "kind": "every", "everyMs": 60000 }, "payload": { "kind": "agentTurn" }, "sessionTarget": "isolated", "delivery": { "mode": "none" }, "enabled": true } EOF ``` The complete source payload also instructs the isolated agent turn to execute `manus-monitor.sh`, check Manus task status, send Telegram notifications when status changes, and remove the cron monitor when no tasks remain. ### Technical Analysis The `save` action automatically invokes `manus-monitor-start.sh`, suppressing all output from that invocation. The invoked script registers an enabled OpenClaw cron entry named `manus-task-monitor`, configured to run an isolated agent turn every 60 seconds. This creates execution that persists beyond the original command and current agent run. The documented behavior in `SKILL.md` describes task creation, polling, and downloading, but does not disclose that saving a task automatically installs a recurring OpenClaw agent task. The recurring execution runs with the permissions available to the OpenClaw account. No operating-system privilege escalation is demonstrated, but the code obtains durable scheduled execution under the user's existing OpenClaw authority. ### Attack Path 1. A user invokes `manus.sh save <task_id>` to save a Manus task identifier. 2. The `save` action automatica ...[truncated 1050 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the automatic call to `manus-monitor-start.sh` from the `save` action. 2. Provide a separate, explicit `monitor-start` command that clearly explains that it installs a recurring OpenClaw task. 3. Require affirmative user consent before registering the scheduled task. 4. Display the schedule, executed script, network destinations, and removal procedure before installation. 5. Prefer a narrowly scoped non-agent polling mechanism if a full recurring `agentTurn` is unnecessary. 6. Do not suppress scheduler-registration errors or status output. 7. Ensure cleanup occurs for completed, failed, invalid, and unreachable tasks. 8. Document how users can inspect and remove the registered cron entry. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/manus.sh:92
Finding
Downloaded Output Files Can Overwrite Existing Files or Follow Symbolic Links<![CDATA[ ## Vulnerability Details **File Location**: `scripts/manus.sh:92-105` **Vulnerability Type**: Unsafe file creation and overwrite **Risk Level**: Medium ### Vulnerable Code ```bash task_id="$1" output_dir="${2:-.}" mkdir -p "$output_dir" curl -s "$API_BASE/tasks/$task_id" \ -H "API_KEY: $MANUS_API_KEY" | jq -r '.output[]?.content[]? | select(.type == "output_file") | "\(.fileName)\t\(.fileUrl)"' | \ while IFS=$'\t' read -r filename url; do if [ -n "$filename" ] && [ -n "$url" ]; then safe_name=$(echo "$filename" | tr -cd '[:alnum:]._-' | head -c 100) [ -z "$safe_name" ] && safe_name="output_file" echo "Downloading: $safe_name" >&2 curl -sL "$url" -o "$output_dir/$safe_name" echo "$output_dir/$safe_name" fi done ``` ### Technical Analysis The script filters characters from the remote filename, which limits direct path traversal through `/` characters. However, it does not verify that the destination is a new regular file. `curl -o` truncates an existing destination and follows a pre-existing symbolic link. Different remote filenames can also collapse to the same sanitized filename after unsupported characters are removed, causing unintended collisions. The output directory is selected by the caller, while filenames and download URLs are supplied by the Manus API response. The script neither rejects existing paths nor verifies that the final resolved path remains a regular file under the intended directory. ### Attack Path 1. The attacker or another local process predicts the sanitized name of a Manus output file. 2. A symbolic link with that name is created in the selected output directory, pointing to another file writable by the victim account. Alternatively, an important existing file uses the same name. 3. The user invokes `manus.sh download <task_id> <output_dir>`. 4. The API returns a filename that sanitizes to the attacker-selected destination name. 5. `curl -o` follows the symbolic link or truncates the existing ...[truncated 577 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Refuse to download when the destination already exists, including when it is a symbolic link. 2. Create destination files atomically with exclusive creation semantics and restrictive permissions. 3. Resolve and validate the output directory before use. 4. Confirm that the final destination remains inside the resolved output directory. 5. Generate collision-resistant local names rather than relying solely on filtered remote filenames. 6. Download into a securely created temporary file and atomically rename it after successful validation. 7. Use `curl --fail --show-error` and verify successful completion before exposing the file. 8. Consider requiring user confirmation before replacing any existing output. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/manus-monitor.sh:65
Finding
Predictable Shared Temporary Log Permits Symbolic-Link File Writes<![CDATA[ ## Vulnerability Details **File Location**: `scripts/manus-monitor.sh:65-67,80,97` **Vulnerability Type**: Unsafe predictable temporary file **Risk Level**: Low ### Vulnerable Code ```bash echo "=== 开始检查任务状态 ===" >> /tmp/manus-monitor.log date >> /tmp/manus-monitor.log ``` Additional writes to the same predictable path occur later in the monitor: ```bash echo "状态变化: $task_id $old_status -> $current_status" >> /tmp/manus-monitor.log ``` ```bash echo "进行中任务数量: $running_count" >> /tmp/manus-monitor.log ``` These source strings are status messages meaning that task checking has started, a status change occurred, and the number of running tasks is being recorded. ### Technical Analysis The script appends to the fixed path `/tmp/manus-monitor.log`. Shared temporary directories are normally writable by multiple local users. The shell redirection follows symbolic links and does not verify the path's owner, type, or permissions. Because the monitor can be invoked by a recurring OpenClaw task, the vulnerable write may occur without an interactive user inspecting the destination first. ### Attack Path 1. A local attacker removes or preempts `/tmp/manus-monitor.log`. 2. The attacker creates `/tmp/manus-monitor.log` as a symbolic link to another file writable by the account running OpenClaw. 3. The recurring monitor executes. 4. Shell append redirection follows the symbolic link. 5. Monitor-controlled log text is appended to the link target. ### Impact Assessment The attacker can append predictable and partially task-derived text to files writable by the Skill's operating-system account. This does not bypass normal file permissions and does not provide arbitrary content control, but it can corrupt configuration or data files and interfere with user-owned scripts or application state. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store logs in the Skill's private data directory instead of the shared `/tmp` directory. 2. Create the log with restrictive permissions such as mode `0600`. 3. Reject symbolic links and files not owned by the expected user. 4. Use a securely opened file descriptor rather than reopening a pathname for every append. 5. If temporary storage is required, create a private directory using `mktemp -d` and clean it up safely. 6. Configure log rotation and size limits to prevent unbounded growth. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/manus-monitor.sh:76
Finding
Task Data Is Embedded Directly into jq Program Source<![CDATA[ ## Vulnerability Details **File Location**: `scripts/manus-monitor.sh:76,84` **Vulnerability Type**: jq expression injection and state corruption **Risk Level**: Low ### Vulnerable Code ```bash old_status=$(echo "$old_status_json" | jq -r ".\"$task_id\" // \"unknown\"") ``` ```bash old_status_json=$(echo "$old_status_json" | jq ".\"$task_id\" = \"$current_status\"") ``` ### Technical Analysis The script constructs jq programs by directly interpolating `task_id` and `current_status` into jq source code. A value containing quotation marks, backslashes, brackets, pipes, or other jq syntax can terminate the intended string or property expression and alter the generated filter. The task ID can enter the local task list through the `save` action, which only checks that it is non-empty. The status value comes from the remote API response. Neither value is passed using jq's data-binding facilities. Shell command execution is not established because the values are expanded inside an already parsed quoted shell argument. The demonstrated risk is jq program manipulation, monitor failure, or modification of the persistent JSON status document. ### Attack Path 1. A crafted task identifier containing jq syntax is supplied to `manus.sh save`, or malformed data is otherwise introduced into `data/task_list.txt`. 2. The scheduled monitor reads the crafted identifier. 3. The value is inserted directly into the jq filter used to read or update `task_status.json`. 4. jq interprets some of the value as program syntax rather than data. 5. The jq command fails or evaluates an altered expression. 6. Monitoring terminates incorrectly, emits errors, or writes corrupted or attacker-influenced status state. A similar condition can occur if an unexpected API response supplies a status string containing jq syntax. ### Impact Assessment The direct impact is limited to the monitoring workflow and its persistent status JSON. A crafted value can cause denial of service, supp ...[truncated 211 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Pass all dynamic values as jq data rather than embedding them in jq source: ```bash old_status=$( jq -r --arg id "$task_id" '.[$id] // "unknown"' "$STATUS_FILE" ) old_status_json=$( printf '%s\n' "$old_status_json" | jq --arg id "$task_id" --arg status "$current_status" \ '.[$id] = $status' ) ``` Additionally: 1. Validate task identifiers against the exact format accepted by the Manus API. 2. Validate status values against the documented allowlist: `pending`, `running`, `completed`, and `failed`. 3. Treat malformed API responses as errors rather than storing arbitrary values. 4. Enable explicit error handling so a failed jq operation cannot silently replace valid state. 5. Write updated JSON atomically and verify it before replacing the existing status file. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description says the skill creates and manages AI agent tasks via the Manus API. The provided code chunk instead sets up a persistent cron monitor that runs every minute to check task status, log activity, notify via Telegram on status changes, and delete itself when no tasks remain. This is a materially different primary behavior from creating/managing tasks through Manus API, and it introduces undeclared capabilities and resources: scheduled execution, openclaw cron infrastructure, and Telegram notifications. Therefore the description does not accurately represent this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description says the skill creates and manages AI agent tasks through the Manus API. The provided code does not create, inspect, or manage Manus agent tasks themselves. Instead, it lists cron jobs from openclaw and deletes any scheduled job named "manus-task-monitor," effectively disabling task monitoring. This is a materially different primary purpose and uses different resources than described, so it is a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description says the skill creates and manages AI agent tasks via the Manus API. The supplied code does not create tasks or manage task configuration/execution; instead, its primary purpose is to periodically monitor existing task IDs, compare statuses against a saved local state file, and notify the user via Telegram when statuses change. It also persists task status locally and writes logs. Monitoring and Telegram notification are materially different capabilities from the declared create/manage purpose, so this is a description-behavior mismatch.

Self-Modification

High
Category
Rogue Agent
Content
fi
    done < "$TASK_LIST"
    
    # Replace original file with updated info
    mv "$temp_file" "$TASK_LIST"

    # 检查是否所有任务都完成了,如果完成则停止监控
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Lp3

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding
The skill documents shell-based curl usage but does not declare any tool scope or allowed-tools boundaries. In an agent environment, missing capability restrictions can allow broader-than-expected command execution and network access, increasing the blast radius if prompts or downstream content are adversarial.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill advises downloading generated files locally and sending them to users without any validation, malware scanning, or sensitivity checks. Because Manus is an autonomous external agent that can browse and produce arbitrary artifacts, those outputs could contain secrets, unsafe content, or malicious files that are then redistributed by the host agent.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The recommendation to always enable createShareableLink can expose task outputs through externally accessible URLs, potentially widening access beyond the intended recipient. If prompts or results contain sensitive data, a shareable link creates an unnecessary disclosure channel and weakens confidentiality controls.

External Transmission

Medium
Category
Data Exfiltration
Content
## Create a Task

```bash
curl -X POST "https://api.manus.ai/v1/tasks" \
  -H "API_KEY: $MANUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This script creates a recurring cron job that will continue polling and may send Telegram notifications based on task state changes, but it does not provide any explicit user warning, consent flow, or disclosure at the point of setup. In an agent skill that can autonomously manage tasks and send external notifications, undisclosed background scheduling and outbound messaging increase the risk of surprise persistence, metadata leakage, and unauthorized notification behavior.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This shell script sends task identifiers to the Manus API and transmits notification content through the Telegram Bot API, while also relying on sensitive environment variables for authentication. Although there is an internal comment and a success log, there is no user-facing warning, confirmation, or disclosure that task information will be sent to external services using API credentials.

External Transmission

Medium
Category
Data Exfiltration
Content
链接:https://manus.im/app/${task_id}"

  # 发送到 Telegram(通过 OpenClaw 消息工具)
  # 这里使用 curl 直接调用 Telegram Bot API
  local bot_token="${TELEGRAM_BOT_TOKEN:-}"
  local chat_id="${TELEGRAM_CHAT_ID:-}"
Confidence
70% 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
local chat_id="${TELEGRAM_CHAT_ID:-}"

  if [ -n "$bot_token" ] && [ -n "$chat_id" ]; then
    curl -s -X POST "https://api.telegram.org/bot${bot_token}/sendMessage" \
      -d "chat_id=${chat_id}" \
      -d "text=${message}" \
      -d "parse_mode=Markdown" > /dev/null
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
# Manus API helper script
# Usage: manus.sh <action> [args]

API_BASE="https://api.manus.ai/v1"
DATA_DIR="$(dirname "$0")/../data"
TASK_LIST="$DATA_DIR/task_list.txt"
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
# Manus API helper script
# Usage: manus.sh <action> [args]

API_BASE="https://api.manus.ai/v1"
DATA_DIR="$(dirname "$0")/../data"
TASK_LIST="$DATA_DIR/task_list.txt"
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
# Manus API helper script
# Usage: manus.sh <action> [args]

API_BASE="https://api.manus.ai/v1"
DATA_DIR="$(dirname "$0")/../data"
TASK_LIST="$DATA_DIR/task_list.txt"
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
# Manus API helper script
# Usage: manus.sh <action> [args]

API_BASE="https://api.manus.ai/v1"
DATA_DIR="$(dirname "$0")/../data"
TASK_LIST="$DATA_DIR/task_list.txt"
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
# Manus API helper script
# Usage: manus.sh <action> [args]

API_BASE="https://api.manus.ai/v1"
DATA_DIR="$(dirname "$0")/../data"
TASK_LIST="$DATA_DIR/task_list.txt"
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
# Manus API helper script
# Usage: manus.sh <action> [args]

API_BASE="https://api.manus.ai/v1"
DATA_DIR="$(dirname "$0")/../data"
TASK_LIST="$DATA_DIR/task_list.txt"
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
# Create a task: manus.sh create "your prompt here" [profile]
    prompt="$1"
    profile="${2:-manus-1.6}"
    curl -s -X POST "$API_BASE/tasks" \
      -H "API_KEY: $MANUS_API_KEY" \
      -H "Content-Type: application/json" \
      -d "{\"prompt\": $(echo "$prompt" | jq -Rs .), \"agentProfile\": \"$profile\", \"taskMode\": \"agent\", \"createShareableLink\": true}"
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The script exceeds simple task management by downloading arbitrary remote files to the local filesystem and maintaining a persistent local task database with auxiliary hooks. In this skill context, Manus tasks can produce attacker-influenced output URLs and filenames, so automatic local materialization of remote content increases the attack surface and creates opportunities for unsafe file handling or persistence abuse.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
Saving a task implicitly launches another local script without prominently informing the user or requiring consent. Hidden secondary execution is dangerous because it creates persistence-like behavior and expands the trust boundary to another script that may run repeatedly in the background.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script starts a background monitoring script automatically and suppresses all output, so users receive no warning that additional code has been executed. This lack of transparency can conceal persistent background behavior and makes review, auditing, and user consent much harder.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The `clear` command removes the entire saved task list file immediately with `rm -f` and provides no confirmation prompt or advance warning. This is an irreversible local data deletion operation and lacks any protective disclosure beyond the command name.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The script's comments and echoed/user-directed text are written entirely in Chinese, including the payload message executed by the agent. This enforces a specific language/locale without any indication of user choice or a documented region-specific justification.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
This shell script includes natural-language comments and user-visible echo messages only in Chinese, such as the status messages on lines 10 and 15. The policy allows locale-specific behavior only when the constraint is documented and justified or when users are given a language choice, which is not present here.

Static analysis

No suspicious patterns detected.