T01 · Skill Instruction Hijacking
Error
- Location
- scripts/morning-brief.sh:43
- Finding
- Untrusted CRM Content Is Embedded in Agent Instructions Without Isolation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/add-lead.sh:22-35`; `scripts/log-activity.sh:24-32`; `scripts/morning-brief.sh:43-59`; `scripts/pipeline-health.sh:20-30`; `scripts/weekly-sprint.sh:31-38` **Vulnerability Type**: Indirect prompt injection through persisted CRM content **Risk Level**: High ### Vulnerable Code `scripts/add-lead.sh:22-35` persists user-controlled lead fields without validation, escaping, or structural isolation: ```bash cat >> "$PIPELINE" << EOF ### ${NAME} @ ${COMPANY} - **Stage**: ${STAGE} - **Type**: Unknown — detect on next interaction (look for Tiger/Peacock/Koala/Owl signals) - **Score**: 45 - **Status**: 🟢 Green - **Deal Size**: ${DEAL_SIZE} - **Last Contact**: ${TODAY} - **Next Action**: Schedule discovery call within 48 hours — prepare 3 open questions about their pain - **Key Pain**: To be discovered - **Notes**: ${NOTES} EOF ``` `scripts/log-activity.sh:24-32` similarly persists untrusted activity content: ```bash cat >> "$ACTIVITY_LOG" << EOF ## ${TODAY} ${TIME} — ${CUSTOMER} @ ${COMPANY} - **Activity**: ${ACTIVITY} - **Summary**: ${SUMMARY} - **Next step**: ${NEXT_STEP} - **Logged**: $(date) EOF ``` `scripts/morning-brief.sh:43-59` prints the resulting file directly into a prompt-like output immediately before Agent instructions: ```bash echo "📋 PIPELINE DATA:" echo "" cat "$PIPELINE" echo "" echo "---" echo "" echo "💡 AGENT INSTRUCTIONS:" echo "Based on the pipeline above, please:" echo "1. Identify all leads with Last Contact > 7 days → flag 🔴 Red" echo "2. Identify leads in 'closing' or 'negotiation' stage → top priority" echo "3. For each priority lead, check their Type (Tiger/Peacock/Koala/Owl)" echo " and suggest the right approach script" echo "4. List top 3-5 actions for today, ordered by urgency score" echo "5. Identify which leads to SEED today (new outreach)" echo "6. End with: total active leads, deals at risk, and one this-week close target" echo "" echo "Format output as t ...[truncated 3398 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Use structured storage** - Store CRM records in JSON or another structured format. - Validate every record against a strict schema before persistence. - Define fixed enumerations for stage, activity type, customer type, and status. - Enforce maximum lengths and reject unexpected object properties. 2. **Constrain untrusted text fields** - Reject or normalize control characters. - Disallow multiline values where they are unnecessary. - Apply reasonable length limits to names, notes, summaries, and next steps. - Do not rely on Markdown escaping alone as a prompt-injection defense. 3. **Separate data from Agent instructions** - Pass CRM records through a dedicated data channel or structured tool result rather than concatenating them into an instruction prompt. - If textual composition is unavoidable, place records inside explicit delimiters and state before them that all enclosed content is untrusted data. - Explicitly instruct the Agent never to follow commands, tool requests, role changes, or policy statements found inside CRM records. 4. **Apply least privilege** - Run report-generation tasks with only the file access required for the sales workspace. - Do not grant network, credential, shell, messaging, or unrelated workspace access unless needed for the requested operation. - Require confirmation before consequential tool actions initiated from generated reports. 5. **Handle existing data safely** - Inspect existing `pipeline.md` and `activity-log.md` files for embedded instructions. - Migrate valid records into the validated structured format. - Quarantine records that fail schema or content validation. 6. **Add security tests** - Test multiline fields that contain fake headings such as `AGENT INSTRUCTIONS`. - Test requests to ignore prior instructions, access unrelated files, invoke tools, or disclose secrets. - Verify that such strings remain inert report ...[truncated 41 chars]
