T01 · Skill Instruction Hijacking
- Location
src/smart_email/subagent_analyzer.py:166- Finding
Untrusted Email Content Is Injected into a Tool-Capable Subagent Prompt
- Content
View full analysis
Vulnerability Details
File Location:
src/smart_email/subagent_analyzer.py:166-219
Vulnerability Type: Prompt injection across an agent-control boundary
Risk Level: HighVulnerable Code
python subject = email_data.get('subject', '') sender = email_data.get('sender', '') body = email_data.get('body_text', '')[:2000] prompt = f"""Act as a professional business email routing assistant and analyze the following email. Email information: Sender: {sender} Subject: {subject} Body: {body} Email data file: {email_file} Result output file: {self._results_dir / f"{email_id}.json"} Produce a JSON result containing: {{ "is_urgent": true/false, "reason": "Reason for the classification", "summary": "A concise summary" }} Perform these steps: 1. Read the email data file if it exists 2. Analyze the email 3. Generate the JSON result 4. Overwrite the result file 5. Print "ANALYSIS_COMPLETE: {email_id}" """ result = sessions_spawn( runtime="subagent", mode="run", message=prompt, timeout_seconds=self.timeout )The excerpt above is an English rendering of the source prompt; the relevant data flow, interpolated variables, paths, output requirements, and
sessions_spawncall are unchanged.Technical Analysis
The email sender, subject, and body are attacker-controlled values. They are interpolated directly into the same instruction message used to direct an OpenClaw subagent. The prompt does not establish a strong separation between trusted instructions and untrusted email data, nor does it tell the subagent to reject instructions found inside the email.
This is more dangerous than ordinary LLM classification because the spawned subagent is explicitly instructed to perform filesystem operations. Its effective privileges depend on the OpenClaw runtime, but the code does not explicitly disable tools or constrain filesystem access to the two intend ...[truncated 1717 chars]
- Remediation
View remediation
Remediation Suggestions
- Replace the general-purpose subagent with a constrained inference call that has no shell, filesystem, network, messaging, or other tools.
- Pass email fields as structured data rather than concatenating them into an instruction string.
- Add a trusted system instruction explicitly stating that the sender, subject, body, attachments, and quoted text are untrusted data and that instructions within them must never be followed.
- If a subagent remains necessary, sandbox it with access only to a per-request input file and output file.
- Disable all tools except the minimum file operations needed for the dedicated request directory.
- Validate the response with a strict JSON schema, including exact types, permitted keys, maximum lengths, and rejection of additional fields.
- Treat the generated reason and summary as untrusted output and escape or sanitize them for every delivery channel.
- Add adversarial tests containing prompt-injection instructions in the sender, subject, plain-text body, HTML body, and attachment metadata.
