T09 · Insecure Skill Coding Practices
- Location
scripts/debate_orchestrator_generic.py:160- Finding
Untrusted Parameters Are Embedded Directly into Tool-Capable Agent Prompts
- Content
View full analysis
Vulnerability Details
File Location:
scripts/debate_orchestrator_generic.py:160-181, with vulnerable prompt construction atscripts/debate_orchestrator_generic.py:282-285,344-348, and367-375
Vulnerability Type: Prompt injection through unsanitized topic and workspace parameters
Risk Level: HighVulnerable Code
python if runtime == "claude": cmd = [ "claude", "-p", prompt, "--model", model, ] elif runtime == "codex": cmd = [ "codex", "-p", prompt, "--model", model, ] result = subprocess.run( cmd, capture_output=True, text=True, timeout=timeout_sec, )The prompts passed to these tool-capable runtimes are constructed using caller-controlled values:
python dispatch_agent( "source_ingest_round_0", f"Execute source-ingest.md: topic={opts.topic}, mode=broad, round=0, " f"depth={opts.depth}, num_queries={num_queries}. " f"Workspace: {workspace}", model_tier="balanced", )python dispatch_agent( f"source_ingest_round_{round_num}", f"Execute source-ingest.md: topic={opts.topic}, mode=focused, " f"round={round_num}, search_focus={search_focus}. Workspace: {workspace}", model_tier="balanced", )python pro_prompt = ( f"Execute debate-turn.md: side=pro, round={round_num}, topic={opts.topic}, " f"mode={opts.mode}, speculation={opts.speculation}, depth={opts.depth}. " f"{prev_round_context}. Workspace: {workspace}" ) con_prompt = ( f"Execute debate-turn.md: side=con, round={round_num}, topic={opts.topic}, " f"mode={opts.mode}, speculation={opts.speculation}, depth={opts.depth}. " f"{prev_round_context}. Workspace: {workspace}" )Technical Analysis
The debate topic can originate directly from the command line or from a configuration file. Both the topic and workspace path are interpo ...[truncated 1897 chars]
- Remediation
View remediation
Remediation Suggestions
- Pass all parameters in a strict JSON envelope rather than interpolating them into free-form control text.
- Delimit each untrusted value and explicitly instruct the runtime that content inside those fields is data, not executable instructions.
- Reject control characters, unexpectedly large topics, and invalid workspace paths before prompt construction.
- Resolve the workspace to a canonical path and require it to remain under an approved workspace root.
- Run delegated agents with a restricted working directory and a filesystem allowlist limited to that workspace.
- Disable shell execution and unrelated tools for roles that only need search, read, and structured write operations.
- Apply network restrictions and destination allowlists where possible.
- Log tool operations independently and require confirmation for access outside the workspace.
- Add adversarial tests containing instruction-like topics to confirm that they remain inert data.
