Back to skill

Security audit

Cancel Dispatch Run

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says, but its cancellation script can be steered outside the intended run directory and may affect unintended local tmux sessions or files.

Review this before installing if other users or processes can influence run IDs or result directories. It should validate project/run IDs, canonicalize paths under RESULTS_BASE, reject traversal and unsafe socket names, and use a unique temporary file for metadata updates.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/run_cancel.sh:47
Finding
Path Traversal Allows Cancellation of Unintended tmux Sessions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run_cancel.sh`, lines 47-49, 61-80, and 84-95 **Vulnerability Type**: Path traversal and insufficient authorization boundary validation **Risk Level**: High ### Vulnerable Code ```bash if [[ "$RUN_ID" == */* ]]; then CANDIDATE="$RESULTS_BASE/$RUN_ID" [[ -d "$CANDIDATE" ]] && TARGET_DIR="$CANDIDATE" else mapfile -t MATCHES < <(find "$RESULTS_BASE" -mindepth 2 -maxdepth 2 -type d -name "$RUN_ID" 2>/dev/null | sort) if [[ ${#MATCHES[@]} -eq 1 ]]; then TARGET_DIR="${MATCHES[0]}" elif [[ ${#MATCHES[@]} -gt 1 ]]; then echo "Error: run-id is ambiguous. Use <project>/<run-id>. Matches:" >&2 printf '%s\n' "${MATCHES[@]}" >&2 exit 2 fi fi if [[ -z "$TARGET_DIR" || ! -d "$TARGET_DIR" ]]; then echo "Error: run-id not found: $RUN_ID" >&2 exit 2 fi META="$TARGET_DIR/task-meta.json" if [[ ! -f "$META" ]]; then echo "Error: task-meta.json not found in $TARGET_DIR" >&2 exit 2 fi TMUX_SESSION=$(jq -r '.tmux_session // ""' "$META") TMUX_SOCKET_NAME=$(jq -r '.tmux_socket_name // ""' "$META") if [[ -z "$TMUX_SESSION" || -z "$TMUX_SOCKET_NAME" ]]; then echo "Error: tmux metadata missing in task-meta.json" >&2 exit 2 fi SOCKET_PATH="$SOCKET_DIR/$TMUX_SOCKET_NAME" TARGET="${TMUX_SESSION}:0.0" set +e tmux -S "$SOCKET_PATH" send-keys -t "$TARGET" -l -- "/ralph-loop:cancel-ralph" tmux -S "$SOCKET_PATH" send-keys -t "$TARGET" Enter sleep 1 tmux -S "$SOCKET_PATH" send-keys -t "$TARGET" -l -- "/exit" tmux -S "$SOCKET_PATH" send-keys -t "$TARGET" Enter sleep 2 tmux -S "$SOCKET_PATH" kill-session -t "$TMUX_SESSION" set -e jq --arg ts "$(date -Iseconds)" '. + {status:"cancelled", completed_at:$ts, exit_code:130}' "$META" > "$META.tmp" && mv "$META.tmp" "$META" ``` ### Technical Analysis When the supplied run identifier contains a slash, it is directly appended to `RESULTS_BASE`. The resulting path is only checked with `-d`; it is not canonicalized, and the script does not verify that ...[truncated 2126 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate both project and run identifiers against a conservative allowlist, such as alphanumeric characters, underscores, periods, and hyphens. 2. Explicitly reject empty components and the special path components `.` and `..`. 3. Canonicalize `RESULTS_BASE` and the candidate directory with `realpath`. 4. Require the canonical candidate path to be a strict descendant of the canonical results root before reading metadata: ```bash BASE_REAL="$(realpath -- "$RESULTS_BASE")" CANDIDATE_REAL="$(realpath -- "$CANDIDATE")" case "$CANDIDATE_REAL" in "$BASE_REAL"/*) ;; *) echo "Error: run directory escapes results base" >&2 exit 2 ;; esac ``` 5. Enforce the documented `<project>/<run-id>` structure rather than accepting arbitrary slash-containing paths. 6. Validate `tmux_socket_name` as a simple socket filename and reject slashes or traversal components. 7. Verify that the resolved socket and session are associated with the selected run, rather than trusting metadata alone. 8. Apply equivalent containment checks after path resolution to mitigate symbolic-link escapes. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run_cancel.sh:95
Finding
Predictable Temporary File Enables Symlink-Based File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run_cancel.sh`, line 95 **Vulnerability Type**: Unsafe predictable temporary file and symbolic-link following **Risk Level**: Medium ### Vulnerable Code ```bash jq --arg ts "$(date -Iseconds)" '. + {status:"cancelled", completed_at:$ts, exit_code:130}' "$META" > "$META.tmp" && mv "$META.tmp" "$META" ``` ### Technical Analysis The metadata update uses a fixed temporary pathname, `task-meta.json.tmp`, in the selected result directory. Shell output redirection opens this path before `jq` executes and follows an existing symbolic link. A local attacker who can modify the result directory can pre-create `task-meta.json.tmp` as a symbolic link to another file writable by the account executing the Skill. When cancellation occurs, the redirection follows that link and truncates or overwrites the target with generated JSON. The subsequent `mv` does not prevent the initial overwrite. After redirection has followed the link, `mv` operates on the temporary directory entry, potentially replacing the original metadata with the symlink while the linked target has already been modified. ### Attack Path 1. A local attacker obtains write access to a result directory that may be cancelled. 2. The attacker creates `task-meta.json.tmp` as a symbolic link to a victim file writable by the Skill's execution account. 3. A cancellation operation is triggered for that run. 4. Shell redirection opens `task-meta.json.tmp`, follows the symbolic link, and truncates the victim file. 5. `jq` writes the generated cancellation metadata into the victim file. 6. The subsequent `mv` cannot undo the overwrite and may additionally replace `task-meta.json` with the temporary symlink entry. ### Impact Assessment The vulnerability can overwrite an arbitrary file writable by the account running the Skill, subject to the attacker being able to create or replace entries in the selected result directory. The overwritten content is const ...[truncated 315 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a unique temporary file in the same directory using `mktemp`: ```bash META_DIR="$(dirname -- "$META")" TMP_FILE="$(mktemp "$META_DIR/.task-meta.json.tmp.XXXXXX")" ``` 2. Install a trap to remove the temporary file on failure or interruption: ```bash trap 'rm -f -- "$TMP_FILE"' EXIT ``` 3. Write the updated JSON to the unique file, set restrictive permissions, and atomically rename it: ```bash jq --arg ts "$(date -Iseconds)" \ '. + {status:"cancelled", completed_at:$ts, exit_code:130}' \ "$META" > "$TMP_FILE" chmod 600 "$TMP_FILE" mv -f -- "$TMP_FILE" "$META" trap - EXIT ``` 4. Verify that the result directory is not attacker-controlled and that it remains beneath the canonical results root. 5. Reject symbolic links for sensitive metadata where appropriate, and ensure directory ownership and permissions prevent untrusted users from creating replacement entries. ]]>
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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep

Static analysis

No suspicious patterns detected.