T01 · Skill Instruction Hijacking
- Location
scripts/write_diary.py:29- Finding
Persistent Workspace Content Is Embedded into Agent Prompts Without Trust Boundaries
- Content
View full analysis
Vulnerability Details
File Location:
scripts/write_diary.py:29-56, 61-65;scripts/weekly_review.py:74-108;scripts/monthly_review.py:88-123
Vulnerability Type: Stored prompt injection through untrusted workspace content
Risk Level: MediumVulnerable Code
python def read_memory_files(yesterday_str): """Read memory files related to yesterday.""" memories = [] memory_file = MEMORY_DIR / f"{yesterday_str}.md" if memory_file.exists(): memories.append( f"=== Yesterday Memory ({yesterday_str}) ===\n" f"{memory_file.read_text()}" ) now_file = WORKSPACE / "NOW.md" if now_file.exists(): memories.append( f"=== Current NOW.md ===\n{now_file.read_text()}" ) if FARM_JSON.exists(): try: farm_data = json.loads(FARM_JSON.read_text()) memories.append( f"=== Farm Status ===\n" f"{json.dumps(farm_data, indent=2, ensure_ascii=False)}" ) except: pass if AUTO_LEARN.exists(): content = AUTO_LEARN.read_text() lines = content.split('\n') recent = '\n'.join(lines[-60:]) if len(lines) > 60 else content memories.append( f"=== Recent Auto-Learn ===\n{recent}" ) return '\n\n'.join(memories) if memories else "No context available"The resulting content is directly interpolated into an Agent prompt:
python def generate_diary_context(context_data, yesterday_str): prompt = f"""You are a diary generation assistant. Generate a structured diary for yesterday ({yesterday_str}) based on the following context. ## Context Data {context_data} ## Output Requirements Generate a diary containing the required summaries, decisions, lessons, next actions, and system notes. """ return promptWeekly and monthly reviews repeat the same pattern by embedding diary-derived content into prompts:
python diar ...[truncated 2925 chars]- Remediation
View remediation
Remediation Suggestions
- Clearly label all loaded workspace text as untrusted reference data and explicitly instruct the Agent never to follow commands found inside it.
- Enclose each source in a strongly delimited data block and identify its source and trust level.
- Prefer structured serialization, such as a JSON object with dedicated data fields, rather than direct free-form interpolation.
- Apply size limits and content validation to every input file before including it in a prompt.
- Separate prompt construction from privileged actions. Generated text should not itself authorize tool calls or determine write destinations.
- Validate Agent output against a fixed schema before writing it to diary or learning files.
- Restrict the review Agent to the minimum required read and write paths, with external messaging disabled during generation unless separately approved.
- Avoid automatically re-ingesting generated text as trusted instructions. Persistent learning entries should be reviewed or filtered before reuse.
- Add adversarial tests in which diary and memory files contain instruction-like text, tool requests, and requests to modify persistent state.
