ASI-06: Sanitize repo-memory and cache-memory content before prompt injection#28777
ASI-06: Sanitize repo-memory and cache-memory content before prompt injection#28777
Conversation
…rompt injection Agent-Logs-Url: https://github.com/github/gh-aw/sessions/27f6b5e7-7029-45bd-825b-bb1f572ab7ed Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
…e and strengthen tests Agent-Logs-Url: https://github.com/github/gh-aw/sessions/27f6b5e7-7029-45bd-825b-bb1f572ab7ed Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
🧪 Test Quality Sentinel ReportTest Quality Score: 63/100
Test Classification DetailsView all 6 tests
Flagged Tests — Requires Review
|
There was a problem hiding this comment.
✅ Test Quality Sentinel: 63/100. Test quality is acceptable — 17% of new tests are implementation tests (threshold: 30%). No coding-guideline violations detected. One low-value test (TestSanitizeMemoryScriptNameConstant) flagged for removal; see comment for details.
There was a problem hiding this comment.
Pull request overview
Adds a pre-agent sanitization layer for persisted memory sources (repo-memory + cache-memory) to mitigate prompt injection / memory poisoning (OWASP Agentic Top 10 ASI-06) by scanning and quarantining suspicious memory files before they’re injected into prompts.
Changes:
- Introduces a new
sanitize_memory.shscanner that quarantines files matching known injection/exfiltration patterns. - Integrates sanitization into cache-memory setup and repo-memory cloning, and emits an explicit, auditable workflow step for repo-memory scanning.
- Updates memory prompt boundary templates to include
sanitized="true"and adds Go tests for step generation + prompt template markers.
Show a summary per file
| File | Description |
|---|---|
actions/setup/sh/sanitize_memory.sh |
New runtime scanner that scans memory directories and quarantines suspicious files with workflow warnings. |
actions/setup/sh/setup_cache_memory_git.sh |
Runs the new scanner after existing pre-agent cache working-tree sanitization steps. |
actions/setup/sh/clone_repo_memory_branch.sh |
Runs the new scanner after cloning/creating repo-memory working directory. |
pkg/workflow/memory_sanitizer.go |
Adds a workflow-step generator for repo-memory sanitization. |
pkg/workflow/repo_memory.go |
Emits an explicit “Scan repo-memory…” step after clone for auditability. |
pkg/workflow/memory_sanitizer_test.go |
Adds tests for step generation and asserts sanitized="true" exists in prompt templates. |
actions/setup/md/repo_memory_prompt*.md |
Adds sanitized="true" attribute to repo-memory prompt boundary tags. |
actions/setup/md/cache_memory_prompt*.md |
Adds sanitized="true" attribute to cache-memory prompt boundary tags. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 10/10 changed files
- Comments generated: 3
| #!/usr/bin/env bash | ||
|
|
||
| # sanitize_memory.sh | ||
| # Pre-agent content scanning for prompt injection in memory files. | ||
| # | ||
| # This script scans text files in a memory directory for known prompt injection | ||
| # patterns (system prompt overrides, role-play injections, instruction-ignoring | ||
| # directives) per OWASP Agentic Top 10 — ASI-06 (Memory & Context Poisoning). |
| } | ||
| builder.WriteString(" env:\n") | ||
| fmt.Fprintf(builder, " GH_AW_SCAN_DIR: %s\n", memoryDir) | ||
| builder.WriteString(" run: bash \"${RUNNER_TEMP}/gh-aw/actions/sanitize_memory.sh\"\n") |
|
|
||
| // Step 2: Scan the cloned memory for prompt injection (ASI-06). | ||
| // The sanitize_memory.sh script is also invoked directly by the clone script, | ||
| // but we emit an explicit step here so that the scan appears in the workflow | ||
| // summary and its output is auditable independently of the clone step. | ||
| generateRepoMemorySanitizationStep(builder, memory, memoryDir) |
|
@copilot address this review feedback #28777 (review) |
…shell tests Agent-Logs-Url: https://github.com/github/gh-aw/sessions/5342e69a-6f8b-403c-a46d-9b8ba7213ced Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Addressed all three review points in commit
Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Persisted memory content (repo-memory and cache-memory) was injected into the agent prompt without any content scanning, enabling Memory & Context Poisoning attacks (OWASP Agentic Top 10 ASI-06): a compromised prior run could write prompt injection payloads into memory, overriding agent instructions on the next run.
Changes
Runtime content scanner (
actions/setup/sh/sanitize_memory.sh)New script that scans text files in a memory directory for 20+ known injection patterns — system prompt overrides (
ignore previous instructions,you are now), role injection markers ([INST],[SYS],<|system|>), jailbreak phrases, and credential exfiltration directives. Suspicious files are moved to a quarantine directory (preserving relative path structure) and emit::warning::annotations. Binary files and.git/are skipped.Cache-memory integration (
setup_cache_memory_git.sh)Added step 4 to the existing pre-agent sanitization sequence (after symlink deletion → execute-bit strip → extension filtering) that calls
sanitize_memory.shagainst the restored cache directory.Repo-memory integration (
repo_memory.go)generateRepoMemorySteps()emits an explicit named workflow step (Scan repo-memory for prompt injection) as the single scanning point for each cloned memory. The scan no longer runs redundantly insideclone_repo_memory_branch.sh.Prompt boundary markers
All four memory prompt templates updated to carry
sanitized="true"on their XML boundary elements, signalling to the model that the enclosed content has been scanned:Go module (
pkg/workflow/memory_sanitizer.go)Provides
generateRepoMemorySanitizationStep()— the single source of truth for emitting the scan step into compiled lock files. The emittedruncommand references thesanitizeMemoryScriptNameconstant to prevent drift if the script is renamed.Tests
pkg/workflow/memory_sanitizer_test.go: Covers step generation for default/wiki/named memories and reads the actual runtime prompt files from disk to assert thesanitized="true"attribute is present.pkg/workflow/sanitize_memory_script_test.go: Executessanitize_memory.shas a subprocess (following the pattern ingit_patch_head_test.go) with 8 test functions covering: clean files, 9 injection pattern categories, relative-path preservation in quarantine,.git/directory exclusion, empty directory, non-existent directory, and mixed safe/suspicious content.