Back to skill

Security audit

Context Anchor

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent context-recovery purpose, but its shell script has a real command-injection flaw in the days parameter that needs review before installation.

Review or patch scripts/anchor.sh before installing. At minimum, validate --days and DAYS_BACK as a bounded positive integer before arithmetic, avoid echo -e for file-derived text, and treat all recovered memory/context content as untrusted orientation data rather than instructions to follow automatically.

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

Error
Location
scripts/anchor.sh:65
Finding
Command Injection Through Unvalidated DAYS_BACK Arithmetic Expression<![CDATA[ ## Vulnerability Details **File Location**: `scripts/anchor.sh`, lines 65–66 and 113–114 **Vulnerability Type**: Shell command injection through recursive Bash arithmetic evaluation **Risk Level**: High ### Vulnerable Code ```bash --days) DAYS_BACK="$2" shift 2 ;; ``` The same value can also be supplied through the environment: ```bash DAYS_BACK="${DAYS_BACK:-2}" ``` It is subsequently evaluated as a Bash arithmetic expression: ```bash get_daily_files() { local files=() for i in $(seq 0 $((DAYS_BACK - 1))); do ``` ### Technical Analysis The script accepts `DAYS_BACK` from either the `DAYS_BACK` environment variable or the `--days` command-line argument without validating that it contains only a bounded positive integer. The value is later used inside: ```bash $((DAYS_BACK - 1)) ``` Bash arithmetic evaluation does not necessarily treat variable contents as inert numeric text. Variable values can be recursively interpreted as arithmetic expressions. Crafted expressions involving array subscripts and command substitution can therefore cause shell commands to execute when the arithmetic expansion is evaluated. In addition, an excessively large numeric value can make `seq` generate an extremely large sequence and cause excessive CPU consumption, memory consumption, or execution time. A zero, negative, malformed, or missing `--days` value can also cause erroneous behavior or abrupt termination under `set -e`. ### Attack Path 1. An attacker gains control over the arguments used to invoke `anchor.sh` or the `DAYS_BACK` environment variable. 2. The attacker supplies a crafted Bash arithmetic expression instead of an integer. 3. The script stores the value without validation. 4. `get_daily_files` inserts the value into `$((DAYS_BACK - 1))`. 5. Bash recursively evaluates the attacker-controlled arithmetic expression. 6. Any embedded command substitution executes with the privileges and environment of the user running the Skill. ...[truncated 700 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Validate the final `DAYS_BACK` value before any arithmetic expansion: ```bash if [[ ! "$DAYS_BACK" =~ ^[1-9][0-9]*$ ]]; then printf 'Error: --days must be a positive integer.\n' >&2 exit 1 fi if (( DAYS_BACK > 365 )); then printf 'Error: --days must not exceed 365.\n' >&2 exit 1 fi ``` Also verify that `--days` has an argument before reading `$2`: ```bash --days) if [[ $# -lt 2 ]]; then printf 'Error: --days requires a value.\n' >&2 exit 1 fi DAYS_BACK="$2" shift 2 ;; ``` Apply validation after parsing so it covers both the environment variable and command-line input. Keep a reasonable upper bound to prevent resource-exhaustion attacks. For additional hardening: - Use `set -euo pipefail`. - Use `readonly` for validated configuration values where practical. - Avoid feeding untrusted strings into Bash arithmetic contexts. - Add tests for missing, negative, zero, malformed, expression-based, and excessively large values. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/anchor.sh:132
Finding
Terminal and Agent-Context Injection Through Unsanitized Memory Content<![CDATA[ ## Vulnerability Details **File Location**: `scripts/anchor.sh`, lines 132–138, 153–159, 179–181, 215–217, and 225–227 **Vulnerability Type**: Unsanitized terminal output and untrusted context injection **Risk Level**: Medium ### Vulnerable Code The current-task file is printed directly: ```bash show_current_task() { header "📋 CURRENT TASK" local task_file="$MEMORY_DIR/current-task.md" if [ -f "$task_file" ]; then echo -e "${DIM}($(relative_time "$task_file"))${RESET}" echo "" cat "$task_file" ``` Active-context content is included in an `echo -e` call: ```bash local preview=$(head -n 5 "$file" | grep -v '^#' | grep -v '^$' | head -n 1) echo -e "${GREEN}• ${name}${RESET} ${DIM}(${age})${RESET}" if [ -n "$preview" ]; then echo -e " ${DIM}└─ ${preview:0:70}...${RESET}" fi ``` Extracted decisions and open-loop content are also emitted through `echo -e`: ```bash local content=$(echo "$line" | sed 's/^[0-9]*://' | sed 's/^[ -]*//') echo -e "${CYAN}[$date]${RESET} $content" ``` ```bash local content=$(echo "$line" | sed 's/^[0-9]*://' | sed 's/^[ -]*//') echo -e "${YELLOW}[$date]${RESET} $content" ``` ```bash local content=$(echo "$line" | sed 's/^[0-9]*://' | sed 's/^- \[ \] //') echo -e "${YELLOW}[current-task]${RESET} $content" ``` ### Technical Analysis The Skill scans files under `memory/` and `context/active/` and presents their contents as a trusted orientation briefing. These files are not sanitized before being written to the terminal. Raw content printed through `cat` can contain terminal control characters. Depending on terminal capabilities, such sequences may change display state, erase or rewrite visible output, create misleading hyperlinks, alter window titles, or interact with terminal-specific features. Several other output paths use `echo -e`, which additionally interprets backslash escape sequences in file-derived content. Consequently, text such as `\033`-style sequences may be ...[truncated 1885 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Treat all content read from memory and context files as untrusted. Replace `echo -e` with `printf` so file-derived backslash sequences are not interpreted: ```bash printf '%s\n' " └─ ${preview:0:70}..." printf '[%s] %s\n' "$date" "$content" ``` Sanitize terminal control characters before output. For example, introduce a helper that removes C0 control characters other than permitted line breaks and tabs: ```bash sanitize_text() { LC_ALL=C tr -d '\000-\010\013\014\016-\037\177' } ``` Use it for every file-derived value: ```bash safe_preview=$(printf '%s' "$preview" | sanitize_text) printf ' └─ %s...\n' "${safe_preview:0:70}" ``` Do not print an entire file directly with `cat`. Sanitize it first: ```bash sanitize_text < "$task_file" ``` Additional hardening should include: - Clearly label scanned text as untrusted file content. - Add explicit start and end delimiters around each file’s output. - Display each source file’s canonical path. - Consider escaping ANSI escape bytes visibly rather than silently removing them. - Prevent untrusted users or processes from writing to the memory and active-context directories. - In Agent integrations, instruct the consumer to treat recovered file content as data rather than executable instructions. - Add tests containing literal control bytes, backslash escape sequences, ANSI hyperlinks, multiline spoofed headings, and instruction-like content. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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
Findings (2)

Vague Triggers

Medium
Confidence
91% confidence
Finding
The description says to use the skill 'when waking up fresh, after compaction, or when you feel lost about what you were doing.' The phrase 'when you feel lost' is subjective and overly broad, making it unclear when the skill should or should not activate.

Vague Triggers

Low
Confidence
88% confidence
Finding
The instruction 'use it manually when you feel lost about context' is an imprecise activation condition without defined scope or exclusions. This can overlap with many normal situations and does not provide negative examples or boundaries.

Static analysis

No suspicious patterns detected.