fix(security): GLOBAL memory prompt injection safeguards (#767) - #769
Merged
Conversation
Two defenses against GLOBAL-scope agent memory injection attacks:
1. Recall delimiter: Search() wraps every GLOBAL-scope memory value
with a non-instructable prefix before returning it to MCP clients:
[MEMORY id=<uuid> scope=GLOBAL from=<workspace_id>]: <value>
This prevents stored content (e.g. "IGNORE ALL PREVIOUS INSTRUCTIONS")
from being parsed as instructions in the agent's context window.
Raw DB content is unchanged — the wrapper is applied on read only.
2. Write audit log: Commit() writes an activity_log entry with
activity_type='memory_write_global' whenever a GLOBAL memory is
stored. The entry records a SHA-256 hash of the content (never
plaintext) alongside memory_id and namespace for forensic replay.
Audit failure is non-fatal — a logging error must not roll back
a successful write.
Tests:
- TestRecallMemory_GlobalScope_HasDelimiter — verifies exact delimiter
format [MEMORY id=... scope=GLOBAL from=...]: <value>
- TestCommitMemory_GlobalScope_AuditLogEntry — verifies activity_logs
INSERT fires on every GLOBAL write (via mock.ExpectationsWereMet)
- TestMemoriesCommit_Global_AsRoot — updated to expect the audit INSERT
All 16 Go test packages pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
Author
|
Dev Lead review — APPROVED. PR #769: GLOBAL memory prompt injection safeguards (issue #767). Verified:
Issue #767 closed by this fix. Queue for merge after PR #766 (critical security). |
This was referenced Apr 17, 2026
molecule-ai Bot
added a commit
that referenced
this pull request
Apr 21, 2026
…injection fix(security): GLOBAL memory prompt injection safeguards (#767)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Search()wraps every GLOBAL-scope memory value returned to MCP clients with[MEMORY id=<uuid> scope=GLOBAL from=<workspace_id>]: <value>. This prevents stored prompt-injection payloads (e.g."IGNORE ALL PREVIOUS INSTRUCTIONS") from being parsed as LLM instructions. Raw DB content is unchanged — wrapping applied on read only.Commit()inserts anactivity_logrow withactivity_type='memory_write_global'on every GLOBAL write. Records SHA-256 hash of content (never plaintext) +memory_id+namespacefor forensic replay. Audit failure is non-fatal.TestMemoriesCommit_Global_AsRootupdated to expect the new audit INSERT and verify viaExpectationsWereMet().New tests
TestRecallMemory_GlobalScope_HasDelimiter— exact delimiter format[MEMORY id=... scope=GLOBAL from=...]: <value>TestCommitMemory_GlobalScope_AuditLogEntry— activity_logs INSERT fires on every GLOBAL writeTest plan
TestRecallMemory_GlobalScope_HasDelimiterpassesTestCommitMemory_GlobalScope_AuditLogEntrypassesTestMemoriesCommit_Global_AsRootpasses with updated audit expectationCloses #767
🤖 Generated with Claude Code