Back to skill

Security audit

Quick Reminders

Security checks for vulnerabilities and agentic risk

Overview

This reminder skill is coherent and mostly disclosed, but it needs review because it runs delayed background message-sending jobs and has local file-handling weaknesses around stored reminder text.

Review before installing. Use it only for non-sensitive reminders and short delays, verify the saved delivery target before relying on it, and prefer hardening the script to use a private 0700 runtime directory, mktemp-created message files, and 0600 permissions for reminders.json.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/nohup-reminder.sh:210
Finding

Predictable Temporary Message File Allows Symlink Clobbering

Content
View full analysis
"$msg_file") ``` ### Technical Analysis The temporary message path is constructed using a workspace checksum and a sequential reminder ID. It is therefore predictable to a local attacker who can determine or guess those values. The shell redirection operator used by: ```bash printf '%s' "$text" > "$msg_file" ``` follows an existing symbolic link. Although `umask 077` protects the permissions of a newly created file, it does not provide exclusive creation and does not prevent symbolic-link traversal. If an attacker creates the expected path as a symbolic link before the reminder is added, the script can truncate and overwrite the linked destination. Exploitation is restricted to files writable by the account running the skill; this issue does not independently bypass operating-system file permissions. ### Attack Path 1. A local attacker determines or predicts `WORKSPACE_KEY`, which is derived from a checksum of the reminder-store path. 2. The attacker determines or guesses the next sequential reminder ID. 3. The attacker creates a symbolic link such as `/tmp/oclaw-rem--.msg` pointing to a file writable by the OpenClaw user. 4. The user creates the corresponding reminder. 5. The script opens the predictable path using ordinary shell redirection. 6. The operating system follows the symbolic link, truncating the destination and writing the reminder text into it. ### Impact Assessment A successful attack can overwrite or corrupt arbitrary files writable by the OpenClaw account. Depending on the se ...[truncated 396 chars]
Remediation
View remediation
"$msg_file" ``` Where available, the implementation should additionally validate ownership and permissions of the runtime directory before using it. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/nohup-reminder.sh:19
Finding

Reminder Store May Expose Plaintext Reminder Metadata Through Permissive File Permissions

Content
View full analysis
"$REMINDERS_JSON"; } ``` Plaintext reminder content and related metadata are subsequently written to that store: ```bash write_json --argjson id "$id" --argjson pid "$pid" --arg text "$text" \ --arg fires_at "$FIRES_AT" --argjson fires_epoch "$fires_epoch" \ --arg created_at "$(date +%Y-%m-%dT%H:%M:%S%z)" --arg msg_file "$msg_file" \ '. + [{id: $id, pid: $pid, text: $text, fires_at: $fires_at, fires_epoch: $fires_epoch, created_at: $created_at, msg_file: $msg_file}]' ``` ### Technical Analysis No restrictive umask or explicit permission mode is applied when `reminders.json` is initially created. Its permissions therefore depend on the environment from which the script is launched. Under a common `022` umask, the file can be created as mode `0644`, making it readable by other local users. The store contains plaintext reminder text, execution times, process IDs, creation times, and temporary message-file paths. Reminder text may contain personal, operational, or otherwise sensitive information. Atomic replacement through `mktemp` and `mv` does not establish the intended confidentiality policy for a store that was initially created with permissive permissions. The script also does not explicitly verify or correct the store's permissions before processing it. ### Attack Path 1. The script is launched under a permissive umask. 2. `ensure_json` creates `reminders.json` without an explicit restrictive mode. 3. One or more reminders are added, placing their plaintext text and metadata in the file. 4. Another local account with filesystem access reads the world- or group-readable reminder ...[truncated 542 chars]
Remediation
View remediation
"$REMINDERS_JSON") || die "failed to create reminders store" fi [[ -f "$REMINDERS_JSON" && ! -L "$REMINDERS_JSON" ]] || die "reminders store must be a regular non-symlink file" chmod 600 "$REMINDERS_JSON" || die "failed to secure reminders store" } ``` The `write_json` function should likewise create its temporary replacement under a restrictive umask and confirm that the final file remains owned by the expected user with mode `0600`. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% 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 · scripts/nohup-reminder.sh (reported line 261)May include surrounding context.

sh
if [[ -n "$msg_file" ]]; then
    rm -f "$msg_file"
  else
    rm -f "/tmp/oclaw-rem-${WORKSPACE_KEY}-${id}.msg" "/tmp/oclaw-rem-${id}.msg"
  fi
  write_json --argjson id "$id" '[.[] | select(.id != $id)]'
  echo "ok: reminder #${id} canceled"

Session Persistence

Medium
Category
Rogue Agent
Confidence
83% confidence
Finding

The skill is designed around detached nohup background processes that persist beyond the interactive session and later perform an external action. This persistence increases risk because queued actions can execute after context changes, user intent is no longer current, or the environment has been repurposed, resulting in delayed unauthorized messaging.

Content

Scanner excerpt · README.md (reported line 5)May include surrounding context.

md
Zero-LLM one-shot reminders delivered via `openclaw message send`. The agent composes the reminder text **at creation time**; at fire time a background process sends it with no LLM invocation — zero tokens consumed on delivery.

Uses `nohup sleep` under the hood, so it's lightweight and doesn't require external schedulers.

Recommended for short-horizon reminders (typically under 48 hours).

Session Persistence

Medium
Category
Rogue Agent
Confidence
91% confidence
Finding

This finding describes the exact deferred execution chain: a detached process sleeps and later invokes 'openclaw message send'. In the context of a messaging skill, that is more dangerous than generic persistence because it enables unattended outbound actions at a later time, which could be abused for spam, harassment, or sending sensitive content after the original conversation has ended.

Content

Scanner excerpt · README.md (reported line 22)May include surrounding context.

md
1. User asks: "Remind me to X in Y minutes."
2. Agent composes a natural-language reminder message and calls the CLI script.
3. The script spawns a detached `nohup sleep <seconds> && openclaw message send ...` process.
4. When the timer fires, the message is delivered and the reminder auto-cleans from the tracking file.

All state is stored in `./reminders.json` (workspace root) — one JSON array of active reminders with IDs, PIDs, text, and fire times.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
89% confidence
Finding

The README explicitly encourages the agent to determine and reuse a delivery target from TOOLS.md so it can send reminders 'without asking'. That creates autonomous outbound messaging behavior and can lead to messages being sent to an unintended recipient or over an unintended channel if the stored target is stale, poisoned, or inferred incorrectly from session context.

Content

Scanner excerpt · README.md (reported line 31)May include surrounding context.

Setup

Add your preferred delivery channel and target to TOOLS.md so the agent knows where to send reminders without asking:

markdown
## Reminders

Session Persistence

Medium
Category
Rogue Agent
Confidence
72% confidence
Finding

The skill is explicitly built around nohup background execution, which creates session-persistent processes that survive the initiating interaction. In this context that behavior is intentional for delayed reminders, but it still increases risk because queued actions can outlive user context, be forgotten, or continue after account/session changes, resulting in unintended message delivery.

Content

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

md
---
name: quick-reminders
description: "Zero-LLM one-shot reminders (<48h) via nohup sleep + openclaw message send, operated via {baseDir}/scripts/nohup-reminder.sh."
metadata: {"openclaw":{"emoji":"⏰","requires":{"bins":["jq","openclaw"]}}}
user-invocable: true
---

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs the agent to send reminder text and delivery targets through external messaging channels, but it does not clearly warn the user that their content and identifiers will be transmitted to third-party services. This creates a privacy and data-handling risk because users may disclose sensitive reminder content or personal contact identifiers without informed consent.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% 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 · scripts/nohup-reminder.sh (reported line 136)May include surrounding context.

sh
# --- usage ---
usage() {
  cat <<'EOF'
nohup-reminder — one-shot reminders via nohup sleep + openclaw message send

Env:
  REMINDERS_JSON   tracking file      (default: ./reminders.json)

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% 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 · scripts/nohup-reminder.sh (reported line 219)May include surrounding context.

sh
# --- usage ---
usage() {
  cat <<'EOF'
nohup-reminder — one-shot reminders via nohup sleep + openclaw message send

Env:
  REMINDERS_JSON   tracking file      (default: ./reminders.json)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script writes the exact reminder text to a file under /tmp, which means user-provided content is persisted on disk outside the shell process. Although the file is permission-restricted with umask 077, there is no prompt, comment, or user-facing warning in the usage text that reminder contents will be stored temporarily in the filesystem.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
70% 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 · scripts/nohup-reminder.sh (reported line 218)May include surrounding context.

sh
(umask 077; printf '%s' "$text" > "$msg_file")

  # Launch detached worker; message text is read from file at fire time.
  nohup bash -c '
    delay="$1"
    channel="$2"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script launches a nohup background worker that later performs an external openclaw message send call using the supplied target and message content. While sending a reminder is part of the script's purpose, the help text does not explicitly disclose that the process continues after the invoking shell exits and will transmit reminder content later via an external messaging channel.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% 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 · scripts/nohup-reminder.sh (reported line 233)May include surrounding context.

sh
REMINDERS_JSON="$reminders_json" "$script_path" remove "$reminder_id" 2>/dev/null || true
  ' _ "$DELAY_SECS" "$channel" "$REMINDER_TARGET" "$msg_file" "$SCRIPT_PATH" "$id" "$REMINDERS_JSON" > /dev/null 2>&1 &
  local pid=$!
  disown "$pid" 2>/dev/null || true

  write_json --argjson id "$id" --argjson pid "$pid" --arg text "$text" \
    --arg fires_at "$FIRES_AT" --argjson fires_epoch "$fires_epoch" \

Static analysis

No suspicious patterns detected.