ASI-06: Sanitize repo-memory and cache-memory content before prompt injection
- Dominant language
- Go
- Stars
- 5.1k
- Forks
- 541
- Avg merge
- 5h 46m
- Merged PRs (30d)
- 760
Description
## Problem
Per the [OWASP Agentic Top 10 — ASI-06 (Memory & Context Poisoning)](https://github.com/microsoft/agent-governance-toolkit/blob/main/docs/OWASP-COMPLIANCE.md), persisted memory that is read back into an agent's context must be scanned for prompt injection before use.
**Current behavior:** Both repo-memory and cache-memory content are restored and injected into the agent prompt **without any sanitization or scanning**.
### Data Flow (Repo Memory)
```
Frontmatter (tools.repo-memory)
→ extractRepoMemoryConfig() [repo_memory.go:L75]
→ generateRepoMemorySteps() [repo_memory.go:L280]
→ clone_repo_memory_branch.sh clones files into ${MEMORY_DIR}
→ collectPromptSections() [unified_prompt_step.go:L100]
→ buildRepoMemoryPromptSection() [repo_memory_prompt.go]
→ Files referenced in raw markdown → directly into agent context
```
### Data Flow (Cache Memory)
```
Frontmatter (cache-memory)
→ generateCacheMemorySteps() [cache.go:L300]
→ actions/cache@ restores ${CACHE_MEMORY_DIR}
→ collectPromptSections() [unified_prompt_step.go:L100]
→ Cache content injected into prompt sections → agent context
```
### Prompt Injection via Memory
The `collectPromptSections()` function in `unified_prompt_step.go` orchestrates 8 prompt sections in order: temp, playwright, trial, **cache**, **repo**, safe-outputs, github, pr-context. Neither the cache nor repo memory sections sanitize their content.
**Attack scenario:** A compromised previous run (or malicious commit to a repo-memory branch) writes prompt injection payloads into memory files. On the next run, these payloads are injected verbatim into the agent context, potentially overriding instructions.
## Parent Issue
Part of #28770 (OWASP Agentic Top 10 Compliance Evaluation)
## Proposed Solution
### 1. Content Scanner Module
Create a `pkg/workflow/memory_sanitizer.go` module that:
- Scans restored memory content for known prompt injection patterns (e.g., system prompt overrides, role-play injections, instruction-ignoring patterns)
- Strips or escapes dangerous patterns before injection
- Logs warnings when suspicious content is detected
### 2. Integration Points
- **Repo memory:** Add sanitization step after `clone_repo_memory_branch.sh` and before prompt section generation in `repo_memory_prompt.go`
- **Cache memory:** Add sanitization step after cache restoration and before prompt section generation
### 3. Prompt Boundary Markers
Wrap memory content in clear boundary markers that the agent can use to distinguish memory from instructions:
```
... content ...
```
### 4. Runtime Validation Script
Add an `actions/setup/sh/sanitize_memory.sh` script that:
- Scans files in `${MEMORY_DIR}` and `${CACHE_MEMORY_DIR}` for injection patterns
- Removes or quarantines suspicious files
- Reports findings via `core.warning()` annotations
### 5. Size & Entropy Limits
- Enforce maximum file size limits on restored memory content
- Flag files with unusually high entropy (potential encoded payloads)
## Key Files to Modify
- `pkg/workflow/repo_memory_prompt.go` — add sanitization before prompt generation
- `pkg/workflow/cache.go` — add sanitization after cache restore
- `pkg/workflow/unified_prompt_step.go` — add sanitized boundary markers
- `actions/setup/sh/` — new sanitize_memory.sh script
- `pkg/workflow/repo_memory.go` — add sanitization step generation
## Acceptance Criteria
- [ ] Memory content is scanned for prompt injection patterns before prompt injection
- [ ] Suspicious content is stripped/escaped with warnings logged
- [ ] Memory content is wrapped in boundary markers in the prompt
- [ ] Existing `cache_memory_threat_detection_test.go` patterns are extended
- [ ] Unit tests cover injection pattern detection
- [ ] No performance regression on memory restoration (< 2s added latency)
Contributor guide
Assessment
This issue has not been assessed yet.