Back to skill

Security audit

Long Running Tasks

Security checks for vulnerabilities and agentic risk

Overview

This skill is coherent for autonomous development, but it should be reviewed carefully because it sets up persistent agents that can change, commit, and push code with weak guardrails.

Use this only for trusted repositories and task files. Start in a sandbox, avoid permission-bypass flags, use a dedicated least-privilege git credential, disable auto-push until changes are reviewed, and prefer a supervised runner with private runtime files and safe prompt passing instead of raw shell interpolation.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T01 · Skill Instruction Hijacking

Error
Location
references/orchestrator-cron.md:66
Finding
Autonomous worker command and instruction injection through untrusted project task content<![CDATA[ ## Vulnerability Details **File Location**: `references/orchestrator-cron.md:66-83`; related worker template at `references/worker-prompt-template.md:7-10` **Vulnerability Type**: Command injection and agent instruction hijacking **Risk Level**: High ### Vulnerable Code ```text Step 4 — Find next task: Read [PROJECT_PATH]/TODO.md Find the first line matching "- [ ]" that does NOT contain "BLOCKED:". If no unchecked non-blocked tasks remain: report "all tasks complete — consider disabling this cron", exit. Step 5 — Spawn worker: Run: cd [PROJECT_PATH] && nohup [AGENT_COMMAND] '[TASK_PROMPT]' > /tmp/lrt-[PROJECT_SLUG]-worker.log 2>&1 & echo $! > $PID_FILE sleep 2 && kill -0 $(cat $PID_FILE) 2>/dev/null && echo "worker verified" || echo "WARNING: worker failed to start" The task prompt must include: - "Read [CONTEXT_FILE] and TODO.md for project context." - The specific task description copied from TODO.md. - "Run tests before committing. Fix failures before proceeding." - "Check off the completed item in TODO.md." - "Commit and push using the project's commit convention." - "Run: openclaw system event --text 'Done: [BRIEF_SUMMARY]' --mode now" ``` Related template: ```text You are working on [PROJECT_NAME]. Read [CONTEXT_FILE] and TODO.md for full context. YOUR TASK: [Paste the specific task description from TODO.md] ``` ### Technical Analysis The orchestrator reads task content from repository-controlled `TODO.md` and copies it into `[TASK_PROMPT]`. That prompt is then interpolated into a shell command inside single quotes: ```sh nohup [AGENT_COMMAND] '[TASK_PROMPT]' ``` No escaping, argument-array construction, content validation, or trust-boundary enforcement is specified. If task or context content contains a single quote followed by shell syntax, it can terminate the quoted argument and inject additional shell commands. The injected commands execute with the operating-system permissions and credentials of ...[truncated 2499 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Do not interpolate prompts into shell source.** - Invoke the agent through an API that accepts an argument array without shell parsing. - Alternatively, store the prompt in a securely created file and pass it through standard input. - Avoid `sh -c`, `eval`, and string-built commands. 2. **Treat project files as untrusted data.** - Clearly delimit copied task content from trusted worker policy. - State that instructions found inside repository files cannot override the fixed orchestration policy. - Reject tasks containing control characters or content outside an explicitly supported format. 3. **Parse structured task data.** - Use a machine-readable task format with separate title, description, allowed paths, and acceptance criteria. - Enforce maximum lengths and strict schemas rather than copying arbitrary Markdown into a prompt. 4. **Constrain worker capabilities.** - Run workers in a filesystem and network sandbox. - Limit writable paths to the intended repository. - Use narrowly scoped deployment credentials. - Prevent access to personal tokens, SSH agents, home-directory secrets, and unrelated repositories. 5. **Require review before publication.** - Disable automatic `git push` by default. - Require human approval or a trusted validation stage before pushing autonomous changes. - Protect sensitive branches with mandatory review and CI checks. 6. **Add provenance controls.** - Only process task files from trusted branches and verified commits. - Do not run autonomous tasks from unreviewed pull requests or attacker-controlled working trees. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
references/orchestrator-cron.md:41
Finding
Predictable shared temporary files permit PID spoofing and unsafe process termination<![CDATA[ ## Vulnerability Details **File Location**: `references/orchestrator-cron.md:41-60`; related file convention at `SKILL.md:35-39` **Vulnerability Type**: Unsafe temporary files and insufficient PID validation **Risk Level**: Medium ### Vulnerable Code ```text LOCK_FILE=/tmp/lrt-[PROJECT_SLUG]-orchestrator.lock PID_FILE=/tmp/lrt-[PROJECT_SLUG]-worker.pid LAST_COMMIT_FILE=/tmp/lrt-[PROJECT_SLUG]-last-commit Step 1 — Acquire lock: If $LOCK_FILE exists: - Read the PID inside it. - If that PID is alive (kill -0 $PID 2>/dev/null succeeds): another orchestrator is running. Exit with "orchestrator already running". - If that PID is dead: the lock is stale. Remove $LOCK_FILE and continue. Write your own PID ($$) to $LOCK_FILE. Set a trap to remove $LOCK_FILE on exit: trap 'rm -f $LOCK_FILE' EXIT Step 2 — Check for running worker: If $PID_FILE exists: - Read the PID inside it. - If PID is alive: - Get latest commit: cd [PROJECT_PATH] && git log --oneline -1 - Get commit timestamp: git log -1 --format=%ct HEAD - If commit is < 30 minutes old: report one-line status ("worker active, last commit: <hash> <age>min ago"), exit. - If commit is >= 30 minutes old: worker is stalled. Kill it (kill $PID), remove $PID_FILE. Include "killed stalled worker" in report. Continue to Step 3. - If PID is dead: remove $PID_FILE. Continue to Step 3. ``` The documented runtime convention also uses predictable shared paths: ```text /tmp/lrt-<project>-worker.pid /tmp/lrt-<project>-orchestrator.lock /tmp/lrt-<project>-last-commit /tmp/lrt-<project>-worker.log ``` ### Technical Analysis The orchestration design places control and state files directly in the shared `/tmp` directory using predictable names derived from a project slug. It does not require: - Private-directory permissions. - Atomic file creation. - Symbolic-link rejection. - Ownership and file-type validation. - Restrictive file permissions. - Validation that th ...[truncated 2533 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Use a private runtime directory.** - Create a per-user or per-project directory under `$XDG_RUNTIME_DIR`. - If `/tmp` must be used, create a random directory with `mktemp -d`. - Set directory permissions to `0700` and verify ownership before every use. 2. **Create files safely.** - Use atomic exclusive creation rather than existence checks followed by writes. - Reject symbolic links and non-regular files. - Set a restrictive `umask`, such as `077`. - Open files with no-follow semantics where the implementation language supports them. 3. **Validate process identity before signaling.** - Require the PID to contain digits only and fall within the valid PID range. - Confirm that the process owner matches the orchestrator account. - Record and verify process start time to detect PID reuse. - Verify the executable, command line, working directory, and a random per-launch identifier. - Refuse to signal the process if any identity check fails. 4. **Use process supervision instead of bare PID files.** - Prefer a service manager, container runtime, cgroup, or subprocess handle that retains reliable process identity. - Signal a dedicated worker process group created by the orchestrator rather than an arbitrary numeric PID. 5. **Use robust locking.** - Use `flock`, an atomic directory lock, or another operating-system-backed locking primitive. - Avoid check-then-create lock logic, which is subject to race conditions. 6. **Separate stall detection from repository activity.** - Record worker heartbeats and verify worker identity. - Do not infer that a process is stalled solely from the age of the latest Git commit. - Attempt graceful termination and revalidate identity immediately before sending any signal. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (13)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
touch /path/to/project/.pause    # pause — orchestrator skips spawning
rm /path/to/project/.pause       # resume
```

The orchestrator still runs on schedule but reports "paused" instead of spawning.
Confidence
85% 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).

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
- **Permission-bypass flags.** Agent CLIs often offer flags that skip safety prompts. Do not use these until you've verified the pipeline in safe mode. See `references/orchestrator-cron.md` for details.
Confidence
80% confidence
Finding
Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

External Model or Provider Selection

High
Category
Excessive Agency
Content
claude

# Codex (sandboxed by default)
codex exec

# Any agent that accepts a prompt argument
<agent-binary> <flags>
Confidence
90% confidence
Finding
Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
```bash
touch [PROJECT_PATH]/.pause     # pause
rm [PROJECT_PATH]/.pause        # resume
```

Or disable the cron job: `cron` tool with `action: "update"`, `patch: { "enabled": false }`.
Confidence
85% 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).

Session Persistence

Medium
Category
Rogue Agent
Content
## Setup

### 1. Create TODO.md in the project root

Structured task queue. Each task must be self-contained enough for a cold-start agent:
Confidence
60% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
Start the first task yourself in safe (default) mode. The orchestrator takes over after this:

```bash
cd /path/to/project && nohup <agent-command> '<task prompt>' > /tmp/lrt-<project>-worker.log 2>&1 &
echo $! > /tmp/lrt-<project>-worker.pid
```
Confidence
88% confidence
Finding
Launching an agent with nohup in the background creates durable autonomous execution outside the initiating session, which is a real persistence mechanism. In this skill's context, that persistence is the feature, but it increases risk because the worker can continue modifying code, using credentials, and pushing commits without real-time human oversight.

Session Persistence

Medium
Category
Rogue Agent
Content
# Project Context File Template

Create this file in the project root (commonly named `CLAUDE.md` or `AGENTS.md`) so cold-start agents have the context they need without exploring the codebase.

```markdown
# [Project Name]
Confidence
60% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
Step 5 — Spawn worker:
  Run:
    cd [PROJECT_PATH] && nohup [AGENT_COMMAND] '[TASK_PROMPT]' > /tmp/lrt-[PROJECT_SLUG]-worker.log 2>&1 &
    echo $! > $PID_FILE
    sleep 2 && kill -0 $(cat $PID_FILE) 2>/dev/null && echo "worker verified" || echo "WARNING: worker failed to start"
Confidence
89% confidence
Finding
Using `nohup` to detach a long-lived worker creates persistent unattended execution that can continue modifying the repository after the initiating session ends. In this context, the background process is explicitly instructed to read project context, perform tasks, and commit changes, which increases the risk of uncontrolled or hard-to-audit actions.

Intent-Code Divergence

Medium
Confidence
85% confidence
Finding
The document explicitly warns against permission-bypass flags, but the overall workflow still directs an autonomous worker to modify code, check off tasks, commit, and push changes based on TODO.md content. That creates a real security risk if project files, task descriptions, or prompts are untrusted, because the agent is still being instructed to perform impactful actions without mandatory human review.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The template instructs workers to modify TODO.md and then commit and push changes without any disclosure that these actions change repository state and may publish work to a remote. In an agent setting, this can lead to unauthorized persistence or exfiltration of code and metadata, especially if the user only intended local analysis or code generation.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The template directs execution of an external command (`openclaw system event ...`) without explaining its effects or obtaining consent. External commands may send data off-host, trigger side effects, or leak task details, making this risky in a generic worker prompt template.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The template creates conflicting instructions: it says not to modify code outside task scope, while also requiring workers to update TODO.md and commit/push changes regardless of whether those actions are within the requested scope. This can normalize out-of-scope repository changes and cause agents to alter project state beyond the user's explicit authorization.

Excessive Permissions

Low
Category
Privilege Escalation
Content
<agent-binary> <flags>
```

> **Security note:** Some agents offer flags that bypass permission checks (e.g., `--dangerously-skip-permissions`, `--yolo`). Do not use these unless you have validated the worker prompts and TODO.md contents in a test repo first. Start with default (safe) mode and only relax permissions after you trust the pipeline.

## Shutdown
Confidence
85% confidence
Finding
Skill requests more permissions than appear necessary for its stated functionality. Review if elevated access is justified.