T01 · Skill Instruction Hijacking
Error
- Location
- scripts/build-cron-payload.sh:49
- Finding
- Stored Prompt Injection Through User-Controlled Reminder Content## Vulnerability Details **File Location**: `scripts/build-cron-payload.sh:49-62` **Vulnerability Type**: Stored instruction injection into a scheduled Agent turn **Risk Level**: High ### Vulnerable Code ```bash payload: { kind: "agentTurn", message: ( "NERVTIMER ARM for timer_id=" + $t.timer_id + ". " + "Run deterministic state transition with: " + "bash " + $base_dir + "/scripts/state.sh start-nagging " + $t.timer_id + ". " + "Then generate one short reminder in the assistant personality. " + "Task: " + $t.title + (if ($t.reason // "") != "" then ". Reason: " + $t.reason else "" end) + "." ) }, delivery: { mode: "announce" } ``` The corresponding validation at `scripts/validate-intent.sh:20-21` only establishes that the title is a nonempty string: ```bash ($root.timer.title | is_non_empty_string) and (($root.timer.schedule_type == "one_shot") or ($root.timer.schedule_type == "recurrent")) ``` ### Technical Analysis The timer's `title`, `reason`, and `timer_id` originate from structured user intent. These values are concatenated directly into the `message` of an `agentTurn`. No unambiguous data delimiters, content-length restrictions, control-character restrictions, or instructions requiring the scheduled Agent to treat these fields exclusively as inert data are applied. Because an `agentTurn` message is interpreted as instructions rather than as a typed data structure, malicious text in a title or reason can be treated as additional instructions. This creates a stored prompt-injection condition: the attacker-controlled content is first incorporated into the cron payload and then interpreted later when the scheduled job runs. ### Attack Path 1. An attacker asks the skill to create a timer with a title or reason containing adversarial instructions, for example text directing the future Agent to ignore the reminder workflow and invoke a ...[truncated 1165 chars]
- Remediation
- ## Remediation Suggestions 1. Keep the scheduled Agent instruction static and pass timer properties through a structured data mechanism rather than interpolating them into prose instructions. 2. Clearly delimit all untrusted fields and state explicitly that their contents are data that must never be interpreted as instructions. 3. Encode structured timer data, such as with JSON, and require the scheduled handler to parse only the expected fields. 4. Enforce maximum lengths and reject control characters or other content that is unnecessary for reminder titles and reasons. 5. Use deterministic code to compose the final reminder where possible, reducing exposure of untrusted content to an instruction-following model. 6. Restrict scheduled Agent sessions to the minimum required tools and permissions so that prompt injection cannot produce unrelated privileged actions. 7. Add tests using titles and reasons containing instruction-like text and verify that the content is reproduced only as reminder data.
