Back to skill

Security audit

Cross Platform Messenger Claw

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent messaging purpose, but its helper script can execute unintended shell commands from user-controlled message or target values.

Review before installing. The messaging capability is expected, but avoid using scripts/notify.sh with untrusted recipients, message text, media paths, or target files unless the eval-based command construction is fixed. Confirm recipients before sending or broadcasting because messages and attachments will be transmitted to external services.

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

Error
Location
scripts/notify.sh:78
Finding

Arbitrary Shell Command Injection Through Unsafe eval

Content
View full analysis

Vulnerability Details

File Location: scripts/notify.sh, lines 78–94 and 98–107
Vulnerability Type: Shell command injection
Risk Level: High

Vulnerable Code

bash
build_cmd() {
  local target="$1"
  local cmd=(openclaw message send --channel "$CHANNEL" --target "$target" --message "$MESSAGE")

  if [[ -n "$MEDIA" ]]; then
    cmd+=(--media "$MEDIA")
  fi
  if [[ "$SILENT" == true ]]; then
    cmd+=(--silent)
  fi
  if [[ "$DRY_RUN" == true ]]; then
    cmd+=(--dry-run)
  fi
  if [[ "$VERBOSE" == true ]]; then
    cmd+=(--verbose)
  fi

  echo "${cmd[@]}"
}

# 发送单条
send_one() {
  local target="$1"
  local cmd
  cmd=$(build_cmd "$target")

  if [[ "$VERBOSE" == true ]]; then
    echo "📤 发送到 $CHANNEL:$target"
  fi

  eval "$cmd"
}

Targets can also originate from standard input:

bash
while IFS= read -r line || [[ -n "$line" ]]; do
  # 跳过空行和注释
  line=$(echo "$line" | xargs)
  [[ -z "$line" || "$line" == \#* ]] && continue

  count=$((count + 1))
  if send_one "$line"; then
    :
  else
    echo "⚠️ 发送到 $line 失败"
    failed=$((failed + 1))
  fi

Technical Analysis

The script initially constructs the OpenClaw invocation as a Bash array, which would preserve argument boundaries if executed directly. However, build_cmd serializes that array into an unescaped string with:

bash
echo "${cmd[@]}"

send_one then passes the resulting string to eval. This causes Bash to parse attacker-controlled values a second time as shell syntax. Consequently, shell metacharacters and constructs contained in --channel, --target, --message, --media, or a target read from standard input can become executable syntax rather than literal OpenClaw arguments.

Quoting values while constructing the original array does not mitigate the issue because those quote boundaries are discarded when the array is flattened. The subsequent eval introduces the vulnerable parsing stage.

Attack Path

  1. An attacker supplies a crafted channel, ...[truncated 1505 chars]
Remediation
View remediation

Remediation Suggestions

Remove eval and preserve the command as a Bash array until execution. Construct and execute the array in the same function:

bash
send_one() {
  local target="$1"
  local cmd=(
    openclaw message send
    --channel "$CHANNEL"
    --target "$target"
    --message "$MESSAGE"
  )

  if [[ -n "$MEDIA" ]]; then
    cmd+=(--media "$MEDIA")
  fi
  if [[ "$SILENT" == true ]]; then
    cmd+=(--silent)
  fi
  if [[ "$DRY_RUN" == true ]]; then
    cmd+=(--dry-run)
  fi
  if [[ "$VERBOSE" == true ]]; then
    cmd+=(--verbose)
    printf 'Sending to %s:%s\n' "$CHANNEL" "$target"
  fi

  "${cmd[@]}"
}

Apply these additional hardening measures:

  1. Never pass user-controlled command text to eval, bash -c, or sh -c.

  2. If command display is required, print a shell-escaped representation without executing it:

    bash
    printf '%q ' "${cmd[@]}"
    printf '\n'
    
  3. Validate CHANNEL against an explicit allowlist of supported channel identifiers.

  4. Validate target formats according to the selected channel where practical.

  5. Treat stdin batch files as untrusted input and pass every line only as a quoted array element.

  6. Add regression tests using values containing spaces, semicolons, command substitutions, redirections, and newline characters to verify that they remain literal arguments.

  7. Run scheduled notification jobs under a dedicated least-privileged account with access only to the credentials and files required for message delivery.

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

Vague Triggers

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill’s trigger description and keyword list are extremely broad, covering common verbs like '发消息', '推送', '通知', and generic platform names. This creates a high risk of accidental activation in ordinary conversations, which is especially dangerous because the skill can perform external message delivery and broadcasting actions across multiple channels, potentially causing unauthorized notifications, spam, or data leakage to third parties.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script executes openclaw message send, which sends user-provided message text, targets, and possibly media to external messaging services. Although the file includes usage examples, it does not clearly warn users that recipient identifiers, message contents, and attachments will be transmitted off-system to third-party channels.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file presents all user-facing guidance exclusively in Chinese, with no indication that alternate languages are available or that the locale restriction is intentional. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

All natural-language documentation, help text, and status messages in the script are written in Chinese, with no option for users to select another language. This can violate language/locale policy when a skill forces a specific language without user opt-in or documented justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.