claude-mem 安全策略解析:命令注入防护、隐私标签体系与本地数据边界
claude-mem 安全策略解析命令注入防护、隐私标签体系与本地数据边界【免费下载链接】claude-memPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode More项目地址: https://gitcode.com/GitHub_Trending/cl/claude-memclaude-mem 是一个常驻后台的记忆增强组件hooks 拦截 Agent 会话、worker 子进程压缩上下文、SQLite/Chroma 落盘存储、本地 HTTP 服务对外提供检索。正因为它会执行系统命令、会管理进程、会读写本地数据、还会把上下文交给外部模型 API仓库根目录的 SECURITY.md 才成为理解其工程安全设计的核心文档。本文基于该文档逐项展开并结合源码印证每一项安全措施的真实实现位置——读完后你将了解 claude-mem 如何系统性防御命令注入、如何用双标签体系做内容隐私控制、哪些数据会离开本机、以及发现漏洞后的标准报告流程。支持版本与漏洞报告流程SECURITY.md 开篇即明确了支持策略只有最新发布版本接收安全更新报告漏洞前应先升级到最新版版本是否受支持latest支持older不支持报告漏洞的规范流程摘自原文档不要创建公开的 GitHub issue、PR 或 discussion通过邮件alexcmem.ai报告或使用 GitHub Security 标签页下的 Report a vulnerability 按钮发起私有安全通告private security advisory报告中应包含复现步骤、影响评估、受影响版本如有建议修复方案一并附上。范围界定该策略覆盖claude-mem插件及其捆绑组件——hooks、worker 服务、SQLite/Chroma 同步、viewer UI、搜索/规划类 skills。上游依赖upstream dependencies的问题应直接报告给对应项目但也可以同步抄送给 claude-mem 维护者。官方承诺对有效报告48 小时内确认并力争在下个版本中交付修复。对于非漏洞类的安全疑问文档建议先阅读安全关键文件中的代码注释或发起 GitHub Discussion而非 Issue敏感问题可直接邮件联系。命令注入防护安全策略的核心防线claude-mem 为 git 操作和进程管理需要执行系统命令这是它最主要的攻击面。SECURITY.md 给出的防御三支柱是数组化参数array-based arguments、显式shell: false、输入白名单校验。安全调用模式文档给出的标准范式// ✅ 安全数组化参数 前置校验 if (!isValidBranchName(userInput)) { throw new Error(Invalid input); } spawnSync(git, [checkout, userInput], { shell: false }); // ❌ 危险字符串插值交给 shell 解释 execSync(git checkout ${userInput});核心逻辑在于只要参数以数组形式传递且shell: false用户输入就只会作为单个 argv 参数到达 git 进程$(...)、; rm -rf、换行符等 shell 元字符没有任何解释机会。仓库中的实际实现文档描述的模式在当前代码库中有明确的落地证据src/shared/spawn.ts 是全项目的 spawn 封装层。spawnHidden()统一注入windowsHide: true而buildSpawnSyncInvocation()处理了 Windows 下.cmd/.batshim 的参数引号转义quoteWindowsCmdArgument()保证含空格的路径在cmd /s /c下不被二次解析——这是数组化参数原则在跨平台场景下的完整体现而不是简单一句shell: false就能覆盖的。src/shared/path-utils.ts 提供normalizePath()反斜杠归一、压缩连续斜杠与isDirectChild()判断文件是否为某目录的直接子项是文件路径用path.join()拼接、防止路径穿越这条规范的具体工具函数。src/shared/worktree.ts 中detectWorktree()解析.git文件时只用statSync/readFileSync 严格正则^gitdir:\s*(.)$提取信息读取失败统一降级为NOT_A_WORKTREE并告警全程不产生任何子进程——展示了能不执行命令就不执行命令的纵深设计。CI 层面的纪律检查spawn 环境隔离除了命令如何执行仓库还防子进程拿到什么环境。scripts/check-spawn-env-discipline.cjs 是一个纯 CJS 的静态检查脚本无需编译步骤即可在 tsc 之前运行它扫描src/下所有.ts文件凡是spawn/spawnSync/spawnHidden调用窗口内出现env:且引用了process.env的地方必须同时出现sanitizeEnv(否则在file:line级别报错并以非零码退出。脚本头部注释说明了动机把裸的process.env传给子进程会让宿主 CLI 的环境变量如CLAUDE_CODE_EFFORT_LEVEL和游离的 Anthropic 凭据如ANTHROPIC_BASE_URL泄漏进 worker 子进程——这对应了 CHANGELOG 中记录的 #2357、#2375 两起真实事故。该规则还有配套测试 tests/env-isolation.test.ts 复用其findViolations逻辑。CHANGELOG 中的安全加固记录CHANGELOG.md 保留了多条与安全直接相关的变更轨迹印证了命令注入是本项目长期重点的事实Security fix: replacedexecSyncwithexecFileSyncto prevent command injection in file path handlingShell injection in sync-marketplace: ReplacedexecSyncwithspawnSyncfor rsync calls to eliminate command injection via gitignore patterns (#1138)Fixed PowerShell command injection vulnerability in worker-utils.tsSecurity enhancement - Switched from execSync to spawnSync with array arguments to prevent command injection。安全审计历史2025-12-16 命令注入漏洞Issue #354SECURITY.md 记录了最近一次正式审计的结论严重级别CRITICAL状态RESOLVED共发现并修复3 处漏洞修复内容在BranchManager.ts中将字符串插值替换为数组化参数新增isValidBranchName()校验函数移除bun-path.ts中不必要的 shell 使用建立完整的安全测试套件。需要说明的是以当前仓库结构看BranchManager.ts已不在src/目录树中该修复属于历史版本的结构但isValidBranchName所代表的分支名白名单校验这一契约被完整保留在了安全规范里。输入校验规则白名单与严格正则SECURITY.md 为三类高频输入给出了明确的校验基线输入类型校验规则分支名必须匹配/^[a-zA-Z0-9][a-zA-Z0-9._/-]*$/且不允许包含..防路径穿越端口号必须为纯数字且落在 1024–65535 区间低于 1024 的保留端口一律拒绝文件路径一律经path.join()归并防止目录穿越这套规则与源码现状互相印证端口纪律体现在 src/npx-cli/cmem-memory-credentials.ts默认 host-observer 端口37777经parsePort()解析并带默认值回退parsePort(...) ?? 37777而非直接透传字符串。路径归并体现在 src/shared/paths.ts数据目录下的所有状态文件如DB_PATH join(DATA_DIR, claude-mem.db)都通过path.join统一构造杜绝手工字符串拼接。进程管理与进程边界SECURITY.md 在 Process Management 一节列出三条PID 文件保护进程 ID 存放在用户数据目录~/.claude-mem/下与数据同域管理端口校验worker 端口在绑定前完成合法性校验健康检查处理请求前先确认 worker 健康状态。从源码结构看这些约束有明确的承载点worker 的 HTTP 中间件 src/services/worker/http/middleware.ts 会校验请求来源只放行http://localhost:/http://127.0.0.1:前缀的 Origin 以及127.0.0.1/::ffff:127.0.0.1来源的客户端 IP——即使 worker 端口因配置失误暴露中间件层仍把访问面收敛到回环地址。进程树管理则集中在 src/supervisor/process-registry.ts、health-checker.ts、shutdown.ts配套的 src/shared/kill-process-tree.ts 处理跨平台的进程组终止并有 tests/shared/ 下的一整套跨平台与 PID 复用回归测试。隐私控制双标签体系与 hook 层剥离SECURITY.md 定义了内容隐私的双标签机制privatecontent/private——用户级隐私命中内容直接不被存储claude-mem-contextcontent/claude-mem-context——系统级标签防止 claude-mem 自己注入的上下文在下一轮被再次记忆防止递归存储。关键在最后一句标签在 hook 层剥离数据到达 worker/数据库之前就已处理。实际实现在 src/utils/tag-stripping.ts且比文档描述覆盖更广——TAG_NAMES白名单实际包含 5 类标签const TAG_NAMES [ private, claude-mem-context, system_instruction, system-instruction, persisted-output, system-reminder, ] as const;实现要点STRIP_REGEX用(name)\b[^]*[\s\S]*?/\1的反向引用匹配成对标签g标志支持一次剥离多个stripTags()返回剥离后的文本与每种标签的剥离计数counts供上层观测这次剥离了多少private块设置了MAX_TAG_COUNT 100的防御阈值单次输入剥离标签超过 100 个时记录告警防异常超大注入刷爆日志另有isInternalProtocolPayload()专门识别整段都是task-notification协议负载的输入上限 256 KiB避免协议消息被当作用户内容入库。该模块有对应的测试覆盖如 tests/utils/tag-stripping.test.ts保证标签剥离行为不随重构漂移。数据存储边界什么在本机什么会离开本机SECURITY.md 的 Data Storage 一节给出了明确的本机数据清单数据位置SQLite 数据库~/.claude-mem/claude-mem.db向量存储Chroma~/.claude-mem/chroma/日志~/.claude-mem/logs/配置~/.claude-mem/settings.json原文明确承诺claude-mem 自身不上传上述任何状态文件也不自行采集遥测所有状态文件数据库、向量库、日志、配置、supervisor 与 PID 文件均写在本地用户目录下。但文档同时给出了一段非常重要的诚实边界说明claude-mem 按设计会调用上游模型提供商与可选集成来完成工作因此 observation/transcript/prompt 内容可能通过这些通道离开本机Claude Agent SDK默认的摘要/观察路径把 prompt 与 transcript 上下文发送到 Anthropic API替代提供商gemini、openrouter配置后同样的上下文改发往对应提供商Chroma MCP /chroma-mcp启用时通过配置的 embedding 后端计算向量该后端依用户配置可能是远程 API对应实现见 src/services/sync/ChromaMcpManager.ts其默认 host 为127.0.0.1且子进程 spawn 显式shell: falseOAuth / keychain 读取spawn 时从平台原生凭据存储读取 Claude Code OAuth tokentoken 仅注入 worker 子进程、不由 claude-mem 本身传输读取实现见 src/shared/oauth-token.tsGitHub Releases / npm registry版本检查与自更新流程从公共 registry 拉取元数据。由此文档给出的操作建议是在发送敏感内容前审阅~/.claude-mem/settings.json与~/.claude-mem/.env中的 provider/Chroma 配置并对确需保护的内容使用private.../private标签将其排除在本地存储之外。权限要求SECURITY.md 声明的运行时权限面文件系统读写~/.claude-mem/与~/.claude/plugins/网络localhost 上的 HTTP 服务默认端口 37777进程管理spawn worker 子进程、管理 PID。明确不需要 root/administrator 提权。端口默认值与源码一致src/npx-cli/cmem-memory-credentials.ts 定义HOST_OBSERVER_DEFAULT_PORT 37777且监听一律绑定127.0.0.1服务器运行时侧 src/server/runtime/ServerService.ts 同样以DEFAULT_SERVER_HOST 127.0.0.1为默认宿主。安全默认值Worker Host默认绑定127.0.0.1仅本机可达Worker Port用户可配置绑定前校验 1024–65535 区间日志级别默认 INFO日志中不落敏感数据隐私标签入库前自动剥离private等隐私内容即上文 tag-stripping 流水线。依赖审计与更新策略文档给出的依赖治理机制每次发版前执行npm auditDependabot 开启自动接收安全更新关键依赖每季度人工复审。更新策略方面安全补丁在发现后尽快发布用户应保持 claude-mem 在最新版本、关注 releases 中的安全公告并查阅 CHANGELOG.md 中与安全相关的变更记录如前文列出的 execSync→spawnSync、PowerShell 注入修复等条目。贡献者安全清单可直接落地的评审基线SECURITY.md 末尾为贡献者提供了三条可操作的规范值得单独摘录因为它们把文档承诺变成了可评审的验收标准。添加命令执行时的铁律// ❌ 绝不 execSync(command ${userInput}); spawn(command, [...], { shell: true }); // ✅ 始终 spawnSync(command, [userInput], { shell: false });处理用户输入的原则白名单优先于黑名单用严格正则做格式校验做类型检查数值做区间校验字符串做长度限制。PR 提交前评审清单无带字符串插值/模板字符串的execSync涉及用户输入时不出现shell: true所有 spawn/spawnSync 调用使用数组参数所有用户可控参数都有输入校验针对新攻击面补充了安全测试代码遵循上述安全模式这份清单与仓库已有的工程化保障check-spawn-env-discipline.cjs的 env 纪律检查、tag-stripping 测试、kill-process-tree 测试矩阵共同构成了规范 → 静态检查 → 自动化测试的三层防线。小结SECURITY.md 不是一份泛泛的安全声明而是一份与代码库强对应的工程合同命令执行侧以数组参数 shell: false 白名单校验为铁律src/shared/spawn.ts、src/shared/path-utils.ts 与 CHANGELOG 中的多次注入修复互为证据数据侧明确划出本机状态文件绝不上传与模型 API 通道内容外发两条边界隐私侧用private/claude-mem-context双标签在 hook 层完成入库前剥离src/utils/tag-stripping.ts边界侧以回环地址绑定与端口区间校验收敛网络面。对使用者最重要的行动项是两条保持最新版本、在发送敏感内容前审阅 provider 配置并使用private标签对贡献者则按贡献者清单在评审前逐项自查。【免费下载链接】claude-memPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode More项目地址: https://gitcode.com/GitHub_Trending/cl/claude-mem创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考