T01 · Skill Instruction Hijacking
Error
- Location
- scripts/generate_daily_memory.py:53
- Finding
- Untrusted Discord Messages Bypass Filtering and Enter Persistent Agent Memory<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/create_agent.sh:202-216` - `scripts/update_agent.sh:68-88` - `scripts/generate_daily_memory.py:53-64` - `scripts/generate_daily_memory.py:229-242` - `scripts/simulate_growth.py:65-85` **Vulnerability Type**: Stored prompt injection and persistent memory poisoning **Risk Level**: High ### Complete Vulnerable Code Snippets `scripts/create_agent.sh:202-216`: ```bash # Step 3: Ingest to SQLite echo "Step 3: Ingesting to SQLite..." python3 "$SCRIPT_DIR/ingest_rich.py" --input "$EXPORT_DIR" --output "$SQLITE_DB" echo " Database: $SQLITE_DB" echo "" # Step 4: Generate memory files echo "Step 4: Generating daily memory files..." python3 "$SCRIPT_DIR/generate_daily_memory.py" --all \ --db "$SQLITE_DB" \ --out "$AGENT_PATH/memory/" ``` `scripts/update_agent.sh:68-88`: ```bash # Step 1: Run incremental export (if guild ID provided and not skipped) if [ -z "$SKIP_EXPORT" ] && [ -n "$GUILD_ID" ]; then echo "[$(date)] Step 1: Running incremental export..." | tee -a "$LOG_FILE" "$SCRIPT_DIR/incremental_export.sh" --guild "$GUILD_ID" --db "$SQLITE_DB" 2>&1 | tee -a "$LOG_FILE" else echo "[$(date)] Step 1: Skipping export (no guild ID or --skip-export)" | tee -a "$LOG_FILE" fi # Step 2: Regenerate today's memory file echo "[$(date)] Step 2: Regenerating memory for $TODAY..." | tee -a "$LOG_FILE" export DISCORD_SOUL_DB="$SQLITE_DB" export DISCORD_SOUL_MEMORY="$MEMORY_PATH" python3 "$SCRIPT_DIR/generate_daily_memory.py" "$TODAY" 2>&1 | tee -a "$LOG_FILE" ``` `scripts/generate_daily_memory.py:53-64`: ```python # Get ALL messages for the day with full content cur.execute(""" SELECT id, content, author_id, author_name, author_nickname, author_color, channel_id, channel_name, channel_category, timestamp, reactions_count, reply_to, message_type, is_pinned, attachments_count, embeds_count, mentions_count FROM messages WHERE date(timestamp) = ? ...[truncated 3622 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Add `safety_status`, `safety_score`, and `safety_flags` to the canonical message schema, with new messages defaulting to `pending`. 2. Run regex and semantic evaluation before every memory-generation operation, including initial creation and incremental updates. 3. Change all memory-generation queries to enforce: ```sql WHERE date(timestamp) = ? AND safety_status = 'safe' ``` 4. Fail closed: do not generate memory when evaluation fails, is unavailable, or leaves messages in `pending` or `unverified` states. 5. Do not wake the agent until filtering completes successfully. 6. Clearly delimit Discord messages as untrusted data and add higher-priority instructions stating that instructions inside messages must never be followed. 7. Use a read-only, sandboxed summarization agent for raw community content. Do not grant it writing, shell, network, messaging, gateway, or agent-spawning tools. 8. Require a separate trusted process to approve proposed persistent-memory changes. 9. Add integration tests proving that `pending`, `regex_flagged`, `flagged`, and `unverified` messages cannot appear in generated memory. ]]>
