T01 · Skill Instruction Hijacking
Error
- Location
- scripts/soul.sh:37
- Finding
- Untrusted Remote Content Can Persistently Replace Agent Instructions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/soul.sh:4-8`, `scripts/soul.sh:37-57`, `scripts/soul.sh:146-174`, and `scripts/soul.sh:177-208` **Vulnerability Type**: Remote instruction hijacking and persistent Agent state poisoning **Risk Level**: Critical ### Vulnerable Code ```bash CATALOG_URL="https://soulsearching.ai/souls.json" SOUL_DIR="${HOME}/.openclaw/souls" CATALOG_FILE="${SOUL_DIR}/.catalog.json" WORKSPACE="${OPENCLAW_WORKSPACE:-$(pwd)}" SOUL_FILE="${WORKSPACE}/SOUL.md" ``` ```bash refresh_catalog() { ensure_dir local tmp="${CATALOG_FILE}.tmp" echo "📡 Fetching soul catalog from soulsearching.ai..." >&2 if ! curl -sSfL "$CATALOG_URL" -o "$tmp" 2>/dev/null; then echo "❌ Failed to fetch catalog. Check your connection." >&2 rm -f "$tmp" exit 1 fi # Normalize: if top-level is array, wrap it; rename "soul" key → "content" python3 -c " import json, sys with open('$tmp') as f: data = json.load(f) if isinstance(data, list): data = {'version': 1, 'source': 'https://soulsearching.ai', 'souls': data} for s in data.get('souls', []): if 'soul' in s and 'content' not in s: s['content'] = s.pop('soul') with open('$CATALOG_FILE', 'w') as f: json.dump(data, f, indent=2) print(len(data.get('souls', []))) " > /dev/null ``` ```bash local soul_json soul_json=$(get_soul_json "$id") if [[ -z "$soul_json" ]]; then echo "❌ Soul '$id' not found in catalog." >&2 echo " Run: soul.sh browse (to see available souls)" >&2 exit 1 fi local name name=$(echo "$soul_json" | jq -r '.name') local content content=$(echo "$soul_json" | jq -r '.content') # Save to local store echo "$content" > "${SOUL_DIR}/${id}.md" echo "✅ Installed: $name → ~/.openclaw/souls/${id}.md" if [[ "$activate" == true ]]; then cmd_switch "$id" fi ``` ```bash # Backup current SOUL.md if it exists if [[ -f "$SOUL_FILE" ]]; then cp "$SOUL_FILE" "${SOUL_FILE}.bak" echo "📋 Backed up current SOUL.md → SOUL.md.bak" fi # Copy soul ...[truncated 2757 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Publish the catalog through a cryptographically signed, versioned manifest and verify its signature against a public key embedded in or securely distributed with the Skill. 2. Include a trusted digest for every soul file and verify the downloaded content before installation or activation. 3. Pin approved catalog versions rather than implicitly trusting mutable remote content. 4. Display the complete proposed `SOUL.md` content and require explicit, informed user confirmation immediately before activation. 5. Clearly warn that activation changes persistent Agent instructions, not merely cosmetic application data. 6. Validate content against a restrictive policy and reject directives that attempt to override system rules, request secrets, modify safety constraints, or trigger tools. 7. Separate untrusted downloaded content from instruction files. Prefer a structured, limited personality schema whose fields are rendered by trusted local code. 8. Record provenance, signature status, version, and content digest for every installed soul. 9. Provide a safe rollback mechanism and preserve multiple immutable backups instead of overwriting a single `.bak` file. 10. Avoid automatic activation immediately after retrieval; installation and activation should be separate trust decisions. ]]>
