来源
2026-07-28 对最近重构范围 b1630e5^...HEAD 的双轴 code review。关联既有安全修复:#204。
问题
src/main/cdf-file-protocol.ts 当前用下面的常量推断文件系统语义:
const CASE_INSENSITIVE_FILESYSTEM = process.platform === 'darwin' || process.platform === 'win32';
随后 isPathWithinRoots() 将请求路径与白名单根整体 toLowerCase() 再做 path.relative()。
操作系统不等于文件系统大小写语义:macOS 可以使用大小写敏感 APFS / 外置卷,Windows 目录也可以启用大小写敏感。若授权根是 /Volumes/Data/Project,同时存在 /Volumes/Data/project,后者会在比较阶段被误判为位于前者内,随后 stat/createReadStream 按原始请求路径读取未授权文件。
这破坏了 AGENTS.md 的 Electron 最小能力边界,也使 #204 的白名单保护在合法文件系统配置下可绕过。
目标行为
- 不再根据
process.platform 猜测路径大小写语义。
- 对已存在的请求目标与白名单根使用文件系统解析后的真实路径进行包含性判断。
- 默认大小写不敏感的 macOS 上,Chromium 将
/Users host-fold 为 /users 时,历史图片/音频仍能正常返回 200。
- 大小写敏感卷上,不同大小写的兄弟目录必须保持不同授权身份。
- 白名单外路径、
.. 逃逸以及根内 symlink 指向根外的目标必须拒绝。
- 缺失文件继续返回 404;越权文件继续返回 403;Range/Content-Type 行为不变。
实现约束
- 高权限判断留在 main;不得把真实路径或额外文件系统能力暴露给 renderer。
- 不按字符串全量 lower-case 代替文件系统身份判断。
- 保持现有
cdf-file URL、preload API 和调用方契约不变。
- 错误响应不得泄漏白名单外真实路径。
测试
在 src/main/cdf-file-protocol.test.ts 增加或调整:
- 默认大小写不敏感文件系统上的 Chromium host-fold 历史资源回归。
- 可同时存在的
Allowed/allowed 兄弟目录:只允许真实授权目录。
- 根内 symlink 指向根外文件返回 403。
..、前缀碰撞(Library / LibraryEvil)继续拒绝。
- Range 请求和普通请求经过同一授权结果。
测试不要通过手工传入 caseInsensitive=true 来证明生产路径正确;应覆盖生产使用的真实路径解析 seam。
验收标准
非目标
- 不扩大允许根集合。
- 不修改
bypassCSP 等与本回归无关的协议注册策略。
- 不引入 renderer 侧授权缓存。
来源
2026-07-28 对最近重构范围
b1630e5^...HEAD的双轴 code review。关联既有安全修复:#204。问题
src/main/cdf-file-protocol.ts当前用下面的常量推断文件系统语义:随后
isPathWithinRoots()将请求路径与白名单根整体toLowerCase()再做path.relative()。操作系统不等于文件系统大小写语义:macOS 可以使用大小写敏感 APFS / 外置卷,Windows 目录也可以启用大小写敏感。若授权根是
/Volumes/Data/Project,同时存在/Volumes/Data/project,后者会在比较阶段被误判为位于前者内,随后stat/createReadStream按原始请求路径读取未授权文件。这破坏了
AGENTS.md的 Electron 最小能力边界,也使 #204 的白名单保护在合法文件系统配置下可绕过。目标行为
process.platform猜测路径大小写语义。/Usershost-fold 为/users时,历史图片/音频仍能正常返回 200。..逃逸以及根内 symlink 指向根外的目标必须拒绝。实现约束
cdf-fileURL、preload API 和调用方契约不变。测试
在
src/main/cdf-file-protocol.test.ts增加或调整:Allowed/allowed兄弟目录:只允许真实授权目录。..、前缀碰撞(Library/LibraryEvil)继续拒绝。测试不要通过手工传入
caseInsensitive=true来证明生产路径正确;应覆盖生产使用的真实路径解析 seam。验收标准
cdf-file:///Users/...资源可读取。pnpm test src/main/cdf-file-protocol.test.ts通过。pnpm run typecheck通过。pnpm run build通过。非目标
bypassCSP等与本回归无关的协议注册策略。