fix(security): GLOBAL memory delimiter spoofing + pin MCP npm version

SAFE-T1201 (#807): Escape [MEMORY prefix in GLOBAL memory content on
write to prevent delimiter-spoofing prompt injection. Content stored
as "[_MEMORY " so it renders as text, not structure, when wrapped with
the real delimiter on read.

SAFE-T1102 (#805): Pin @molecule-ai/mcp-server@1.0.0 in .mcp.json.example.
Prevents supply-chain attacks via unpinned npx -y.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hongming Wang 2026-04-18 11:09:24 -07:00
parent 0d538ab27a
commit a61dadde43
2 changed files with 9 additions and 1 deletions

View File

@ -3,7 +3,7 @@
"molecule": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@molecule-ai/mcp-server"],
"args": ["-y", "@molecule-ai/mcp-server@1.0.0"],
"env": {
"MOLECULE_URL": "http://localhost:8080"
}

View File

@ -179,6 +179,14 @@ func (h *MemoriesHandler) Commit(c *gin.Context) {
content := body.Content
content, _ = redactSecrets(workspaceID, content)
// SAFE-T1201: prevent delimiter spoofing in GLOBAL memories (#807).
// If content contains the delimiter prefix "[MEMORY ", an attacker could
// craft a fake nested delimiter to inject instructions when the memory
// is read back. Escape the bracket so it renders as text, not structure.
if body.Scope == "GLOBAL" {
content = strings.ReplaceAll(content, "[MEMORY ", "[_MEMORY ")
}
var memoryID string
err := db.DB.QueryRowContext(ctx, `
INSERT INTO agent_memories (workspace_id, content, scope, namespace)