为什么扔进 Obsidian 知识库的文件要先过五道关卡:claude-obsidian 恶意归档防御机制一文看懂

为什么扔进 Obsidian 知识库的文件要先过五道关卡:claude-obsidian 恶意归档防御机制一文看懂 为什么扔进 Obsidian 知识库的文件要先过五道关卡claude-obsidian 恶意归档防御机制一文看懂【免费下载链接】claude-obsidianSelf-organizing AI second brain for Obsidian Claude Code. Drop any source and Claude reads, links, and files it into one connected knowledge graph of plain Markdown you own. AI note-taking, personal knowledge management (PKM), and an open-source Notion alternative. Based on Karpathys LLM Wiki pattern.项目地址: https://gitcode.com/GitHub_Trending/cl/claude-obsidian把任意来源的资料丢进一个本地知识库听起来很美好但也是把攻击面交给了文件系统。claude-obsidian 是一个开源的 AI 第二大脑归档工具你把文件放进inbox/收件箱它就负责读取、建立链接并归档成一组互相连接的纯 Markdown 笔记全部归你所有。为了让扔文件进来这件事真的安全项目围绕归档入口构建了一整套恶意归档防御机制覆盖路径穿越、符号链接、文件名混淆、资源耗尽、内容篡改与并发冲突等典型风险。本文就顺着一个文件从进门到落盘的完整旅程看看它在每一步会遇到什么威胁、被哪道关卡拦下。 进门安检归档前的路径穿越防护威胁场景很直接一个形如../../etc/passwd的相对路径如果照单全收写入操作就会溜出库外。claude-obsidian 的做法是先纸面审问再实地核查。第一步是纯词法校验_validate_relative_directory与事务层的_normalize_vault_path会拒绝绝对路径、反斜杠、空段和..段并要求路径已经规范化、文件名通过 NFC 归一化NFC 是 Unicode 的一种标准写法保证同一个字符只有唯一编码形式、长度不超过 240 字节。但词法上干净的a/b.md其中的a完全可能是一个符号链接悄悄指向库外。于是第二步在真实文件系统上复核assert_within先把路径里存在的符号链接全部解析掉再确认最终落点仍位于库根之内否则抛出PATH_OUTSIDE_VAULT。对用户而言这意味着无论调用方传进什么路径写操作被锁死在知识库目录内部失败时得到一个明确的错误码而不是一个被写坏的系统文件。 链接伪装为什么每一段路径都不允许是符号链接符号链接是本地文件安全的头号伪装者——它外表是库里的一个普通条目实际却可能是指向任意位置的快捷方式。claude-obsidian 对它的策略是零容忍而且检查点覆盖整条路径收件箱根目录若是链接会触发SOURCE_ROOT_SYMLINKinbox 内任意目录条目是链接会触发SOURCE_SYMLINK.raw内容寻址仓库是链接会触发RAW_STORE_SYMLINK而事务写入路径的每一段目录都会被_safe_vault_path用lstat逐一摸一遍发现链接或 Windows 目录联接即报SYMLINK_WRITE_PATH。特别值得注意的是_allowed_source_path的逐段走查它从收件箱根一路走到源文件途中任何一级目录被替换成别名都会以SOURCE_OUTSIDE_INBOX中止——即使那个源文件本身干干净净。对普通用户来说这条规则的价值在于眼见为实你看到的收件箱结构就是归档时真实走过的结构不存在中途被人换成暗道的可能。 名字混淆文件名卫生与大小写别名攻击威胁往往藏在细节里以空格或点结尾的文件名在 Windows 上会被系统悄悄裁掉尾部字符Note.md与NOTE.MD在不区分大小写的文件系统上是同一个文件攻击者就能利用这种两个名字指向一份内容的歧义绕过检查。_validate_filename一次性挡掉这批问题控制字符、零宽格式字符、首尾空格、Windows 保留设备名CON、NUL等、非 NFC 名称全部拒绝统一报UNSAFE_FILENAME。更隐蔽的一层在写入侧_assert_no_existing_portable_alias会枚举目标目录的所有兄弟条目把每个名字做 NFC casefoldcasefold 是比转小写更彻底的大小写与重音不敏感比较之后互相比对一旦发现已有文件与新路径构成别名立即抛出CASEFOLD_PATH_ALIAS。这意味着在 Mac、Linux 上归档、再把库拷到 Windows 使用时不会出现同名文件互相覆盖的诡异行为权限判断也不会被别名混淆。 落盘验封内容寻址为何让重复归档不可篡改威胁场景文件已经归档过一次但如果.raw/里那份副本后来被外部偷偷改过字节二次归档时你以为在复用旧数据实际读到的是被调包的内容。claude-obsidian 的答案是把源文件复制成摘要值加扩展名存进.raw/captured/——文件的名字就是它的内容指纹。SHA-256 是一种哈希算法可以把任意大小的内容压成一段固定长度的指纹内容差一个字节指纹就完全不同。source_identity计算指纹期间会比对读取前后的 inodeinode 是文件系统为每个文件分配的唯一编号相当于文件的身份证号、大小和修改时间任何一方对不上就抛出SOURCE_CHANGED——你归档的永远是你亲眼看到的那份内容。而_find_existing_capture在发现同指纹的旧副本时还要重新算一遍字节名字对得上但内容对不上说明仓库被外部动过报IMMUTABLE_SOURCE_CONFLICT。原始资料区由此成为只创建、永不修改的保险柜。同一关还站着资源预算岗CaptureBudget规定单批最多 100 个文件、单文件不超过 64 MB、整批不超过 256 MB超限分别报COUNT_BUDGET_EXCEEDED、FILE_BUDGET_EXCEEDED、TOTAL_BUDGET_EXCEEDED。这不是提示性的建议值而是失败即中止的硬门槛超大文件、海量小文件、巨型队列文档都在这一步被挡在磁盘之外。 并发踩踏锁、所有权令牌与冲突回滚威胁场景两个进程同时操作同一个库就像两个人同时在一张表上盖章签字谁先谁后没有规矩结果就是数据互相覆盖。捕获队列用的是目录型锁CaptureQueueLock锁目录的创建是原子操作创建失败就说明已有持有者持有者随即写入包含 pid、主机名和随机 token 的 owner.json释放之前还要回读校验 token 没变防止锁在半路被偷换QUEUE_LOCK_OWNERSHIP_LOST。死锁恢复也保持克制——只有确认持有进程确实已死且锁已超龄才会清理且清理前再复查一次锁身份。事务层transaction.py则用预检哈希 持久日志 原子替换兜底每个写入都事先记下目标的预期 SHA-256中断后执行回滚时逐字节验证目标没被换过对不上就报ROLLBACK_TARGET_CHANGED并停止绝不带着怀疑的状态继续。所有冲突都归入明确的CaptureConflict错误家族而不是静默失败这对你意味着无论多进程的踩踏多激烈库要么完整、要么完整回滚且你会拿到一个能直接定位原因的确定性错误码。 附外部 URL 的 SSRF 边界外部链接类适配器同样被锁死validate_https_url只接受 HTTPS 方案_validate_public_host拒绝localhost、169.254.*、.internal等私有与本地主机甚至包括用十六进制或纯数字编码 IP 的变体写法URL_PRIVATE_HOSTvalidate_redirect_chain则要求重定向后的每一跳都必须落在显式批准的主机白名单内REDIRECT_HOST_FORBIDDEN。所有外部动作只能先生成惰性计划必须你明确同意才会真正执行。这一段篇幅从简但原则一致网络出口和文件入口一样默认全部关闭。写之前所有路径、文件名、预算和 URL 都已在任何 IO 发生前完成纯纸面审查不合格者连库的门都摸不到写之中内容指纹全程伴读符号链接逐段排除每一笔修改都带着预期哈希和可回滚的日志落盘写之后原始副本以摘要命名永久封存任何人动了字节都会在下次归档时原形毕露。这套设计没有任何一处依赖攻击者不会这么做的假设安全边界的完整声明见 SECURITY.md核心实现集中在 capture.py、transaction.py 与 paths.py。如果你想亲手体验一次完整的归档流程可以先克隆仓库 https://gitcode.com/GitHub_Trending/cl/claude-obsidian 初始化一个独立知识库再把任意文件丢进inbox/看看每一道关卡如何依次生效。【免费下载链接】claude-obsidianSelf-organizing AI second brain for Obsidian Claude Code. Drop any source and Claude reads, links, and files it into one connected knowledge graph of plain Markdown you own. AI note-taking, personal knowledge management (PKM), and an open-source Notion alternative. Based on Karpathys LLM Wiki pattern.项目地址: https://gitcode.com/GitHub_Trending/cl/claude-obsidian创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考