3.0 KiB
GHSA Draft: Incomplete secret redaction in agentmemory privacy filter
Severity: Medium · CVSS 3.1: 6.2 (AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
CWE: CWE-532 — Insertion of Sensitive Information into Log File, CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor
Affected versions: < 0.8.2
Patched version: 0.8.2
Summary
agentmemory's privacy filter (src/functions/privacy.ts) is supposed to strip API keys, secrets, and bearer tokens from captured observations before they are stored. The filter used regex patterns to detect common token formats. Three modern token formats were missing from the patterns:
- Bearer tokens —
Authorization: Bearer <token>headers were not matched, so any captured HTTP request or response that included an Authorization header flowed into the memory store verbatim. - OpenAI project keys —
sk-proj-*(the dominant OpenAI API key format since mid-2024) was not matched. The existingsk-[A-Za-z0-9]{20,}pattern only caught the legacy format. - GitHub fine-grained service/user tokens —
ghs_*andghu_*were not matched. The existingghp_[A-Za-z0-9]{36}pattern only caught personal access tokens.
Impact
agentmemory's README explicitly claimed "Privacy first — API keys, secrets, and <private> tags are stripped before anything is stored." That claim was false for three common token formats.
Users relying on the privacy filter to protect their captured observations had a false sense of security. Tokens matching these three patterns would:
- Be captured by
PostToolUsehooks alongside the rest of the tool output - Pass through
stripPrivateData()unmodified - Be LLM-compressed and stored in the memory KV
- Be exposed to any attacker who could reach the
/agentmemory/exportor/agentmemory/smart-searchendpoints - Be included in Obsidian exports, mesh syncs, and CLAUDE.md bridge writes
When chained with advisory #03 (default 0.0.0.0 binding), this meant network-adjacent attackers could retrieve captured Bearer tokens, OpenAI keys, and GitHub service tokens from the memory store.
Patches
Fixed in 0.8.2:
New regex patterns added to SECRET_PATTERN_SOURCES in src/functions/privacy.ts:
/Bearer\s+[A-Za-z0-9._\-+/=]{20,}/gi,
/sk-proj-[A-Za-z0-9\-_]{20,}/g,
/(?:sk|pk|rk|ak)-[A-Za-z0-9][A-Za-z0-9\-_]{19,}/g,
/gh[pus]_[A-Za-z0-9]{36,}/g,
Three new unit tests in test/privacy.test.ts verify each format is now stripped.
Workarounds
Users on affected versions should:
- Avoid having agents read files or API responses containing these token formats
- Use the
<private>tag around any block containing secrets — that filter was not affected - Set
AGENTMEMORY_SECRETto restrict API access - Upgrade to 0.8.2
References
Credit
@eng-pf