[插件mimosa] Git 门禁集成缺陷:排除项被忽略、误报无处置途径、卸载不生效(无出口闭环)
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 22
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
环境:macOS 15(darwin 27.0.0, arm64),ZCode CLI + zcode-plugins-official/mimosa 1.0.3。项目是 Bun + TypeScript 的 Web Components 库,带一个由已审计源码构建生成的压缩文档产物(docs/assets/main.js,gitignore 的生成输出)。
摘要:五个集成缺陷叠加,导致 agent 侧的每次 git commit 都被一组既无法修复、也无法处置、还关不掉的 finding 永久阻断。每个行为单独看都有其道理;合在一起构成一个没有出口的闭环。
1. commit 门禁忽略 threatModel.exclusions
.mimosa/security-policy.json 声明了 threatModel.exclusions: ["docs/**", "docs/"],policy check 与 threat-model check 均通过;目录审计遵守该排除项。但 L3 commit 门禁(PreToolUse 拦截含 git commit 的 Bash 命令)不遵守:它扫描被排除的路径并硬阻断 —— 我们的案例中是生成产物 docs/assets/main.js 内的 2 个 high 与 7 个 medium。
期望:门禁与审计遵守同一套排除项,或文档说明门禁另有单独的排除机制。
2. 无法修复的误报没有处置途径(与 #300 呼应)
mimosa validate <finding-id> 拒绝一切非 fixed_static 状态的 finding:
✗ 只有 fixed_static finding 可进入运行复验;当前为 blocked
mimosa-ignore 注释在门禁模式下又被 --no-ignore-comments 禁用(对不可信代码这样设计本身是合理的)。于是生成产物上的误报没有任何出口:产物每次构建都从已审计的源码重新生成,finding 随之回来,而没有任何机制能把它标记为「已人工复核」。具体案例:我们产物里唯一的 exec( 是分词循环中的 RegExp.prototype.exec,整个文件不含任何 SQL 关键字 —— 两条分别被报成命令注入与 SQL 注入,依据只是压缩后的标识符名。
期望:同 #300 请求的密封处置流(finding 级误报判定 + 理由,写入 ledger,门禁遵守)。补充一点:在门禁遵守排除项/处置结果之前,validate 至少应能受理 blocked 状态的 finding。
3. git-gate uninstall 关不掉真正拦截的那一层
mimosa git-gate uninstall 报告成功并声称恢复了安装前的 hook;随后 ZCode 的 PreToolUse Bash 钩子仍以完全相同的 finding 阻断 git commit。值得注意:前后 .git/hooks 里都不存在任何 Mimosa hook —— 真正拦截的是插件注册的 ZCode 钩子层,uninstall 并未触及。
期望:uninstall 停用真正拦截的那一层;或文档说明 ZCode 钩子层需另行禁用插件。
4. 文件扫描中的 advisory 到门禁侧变成阻断 high
mimosa scan <file> --json 将入口点类 finding(如 runCommand 是 command-injection 入口)标为 "advisory": true;门禁的阻断信息却把同一批 finding 计入「6 个高危」并硬阻断。同一 finding 两套阻断语义,使用者无法从扫描输出推断什么会挡住 commit。
期望:扫描与门禁采用一致的阻断语义。
5. 结构化规则不识别任何净化器写法(已实测,与 #300 呼应)
两次实测(改动后均重新扫描确认):
- 在
fetch(dynamicUrl)调用前一行内联new URL()+ 同源 +http:/https:协议校验,仍报 SSRF(CWE-918)—— 而且这是浏览器端代码,本不存在服务端请求伪造的语境。 - 在同一函数内对每个动态元素做严格白名单校验(组件名 kebab-case 正则;透传参数逐个检查
--flag/--flag=value形态),spawn(prog, computedArray)仍报 CWE-88。
一个文档明示用途就是透传任意 Playwright 参数的 CLI 测试跑批器,不放弃自身功能就无法满足前一条规则;构建脚本以静态参数 spawn bun build 同理。这与 #300 在 Python/SQLAlchemy 侧观察到的「守卫不被识别为净化器」是同一类问题。
期望:文档化一批被识别的净化器模式(URL 同源/协议校验、白名单校验)并使其切断污点边;在此之前,「修复后重扫」对合法的工具代码不可执行。
6. 次要:钩子把状态写进嵌套目录,破坏基线捕获
某次钩子以别的工作目录运行,在项目内创建了 .agents/skills/<skill>/.mimosa/hook-state/*。此后每次 Stop 钩子的基线捕获都报 snapshot_error_count: 2(baseline_snapshot_unreadable —— 600 权限的状态文件在捕获期间自身仍在被写),所有批次记为 inconclusive/partial,进而又使 validate 拒绝运行(「finding ledger 为 partial」)。删除该杂散目录后恢复正常。建议钩子状态固定写入工作区根目录,并把自身状态目录排除在基线捕获之外。
建议优先级:1 + 2 是「无出口闭环」的核心;3 是打不开的逃生门;4–6 可独立处理。与 #300 的关系:#300 从功能角度请求豁免机制与净化器建模,本 issue 补充门禁集成侧的缺陷证据 —— 特别是「已声明且校验通过的排除项在门禁被忽略」与「uninstall 不生效」两点,各自独立成立。
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the reported behavior with .mimosa/security-policy.json, docs/assets/main.js, and the stated mimosa policy, scan, validate, and git-gate commands. Compare audit exclusions, advisory handling, finding validation, uninstall behavior, and hook-state snapshots; done requires the affected layers to apply consistent rules and provide a usable resolution path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, typescript
- Domain
- cli, devtools, security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100