T01 · Skill Instruction Hijacking
- Location
scripts/agent-wake.py:62- Finding
Arbitrary Caller-Controlled System Message Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/agent-wake.py:62-84
Vulnerability Type: System-level instruction injection
Risk Level: CriticalVulnerable Code:
python def wake(message: str, channel_id: str = "") -> bool: """ Fire a cron wake event into the agent session. If channel_id is provided, targets that specific Discord channel session. Otherwise targets the main session. """ if not GATEWAY_TOKEN: print("ERROR: GATEWAY_TOKEN not set. Check your .env file.", file=sys.stderr) return False event_text = message if channel_id: event_text = ( f"{message} -- Send your response to Discord channel {channel_id} " f"(use message tool, action=send, target={channel_id}). " f"Do not respond anywhere else." ) body: dict = { "tool": "cron", "args": { "action": "wake", "text": event_text, "mode": "now", }, }The privileged nature of the injected content is explicitly documented in
SKILL.md:52-58:markdown ## What the agent receives The event text is injected as a system message. Be specific -- the agent acts on what you write:Build finished -- 3 errors fixed, tests passing. Send your response to Discord channel 1475232925724315740...
text Technical Analysis
The first command-line argument is accepted as arbitrary text and copied directly into the
textproperty of an immediatecronwake event. According to the Skill documentation, this text is injected into the target agent session as a system message rather than as untrusted notification data.No validation, instruction filtering, event-type allowlist, trust boundary, or separation between data and instructions is applied. Consequently, a caller that can invoke the script can submit imperative content designed to alter ...[truncated 2327 chars]
- Remediation
View remediation
Remediation Suggestions
- Never place caller-controlled text into a system message or another privileged instruction channel.
- Deliver external completion notifications as explicitly untrusted event or user data, accompanied by an immutable instruction that the content must not be treated as commands.
- Replace free-form messages with a strict schema containing allowlisted fields such as task identifier, status, timestamp, and a length-limited summary.
- Reject imperative control fields and validate message length, encoding, and permitted event types.
- Authenticate each event producer independently and bind its credential to approved agents, sessions, event types, and Discord channels.
- Do not derive session routing or message-tool destinations directly from caller-controlled channel IDs. Use a server-side allowlist mapping trusted task identities to fixed destinations.
- Require explicit user confirmation before the agent performs consequential tool calls in response to an external wake event.
- Apply least privilege to the gateway token and target agent so that a notification producer cannot invoke unrelated gateway tools.
- Record and monitor event producer identity, destination session, event type, and resulting tool activity.
