Skip to content

fix(safety): protected paths need one confirmation even in full mode (O94) - #93

Merged
QiaolongLi1201 merged 3 commits into
mainfrom
fix/o94-protected-paths
Oct 11, 2026
Merged

QiaolongLi1201 merged 3 commits into
mainfrom
fix/o94-protected-paths

Conversation

@QiaolongLi1201

@QiaolongLi1201 QiaolongLi1201 commented Oct 11, 2026 •

Copy link
Copy Markdown
Collaborator

O94: full 模式下写受保护路径也要问一次

Problem

信任工作区不等于同意改 ~/.ssh、.bashrc、.git、.env 或 Moss 自己的配置。默认 full 模式对普通路径的行为不变;只在写入 / 删除 / 移动受保护路径时多问一次(-p / 非交互直接拒绝)。

Change

  1. 策略层 src/safety/protected-paths.ts:分类受保护路径(.git/、~/.ssh/、shell rc/profile、.env / .env.* / .envrc、Moss 配置与信任文件);realpath + 大小写无关匹配;软链接 / ../ 绕过有测。
  2. Shell 目标来自 O97 共享模块 detectShellWriteTargets(src/safety/shell-write-detect.ts)。命中规则:
    • 任一 known target 是受保护路径 → 确认 / -p 拒绝
    • uncertain=true 且 mentions(或命令文本)点名受保护路径 → 确认 / -p 拒绝
    • uncertain 但没有任何受保护引用(如 python script.py)→ 不问(约定行为)
  3. O94 补充:O97 不把 chmod / chown / chgrp 当写入;本 PR 本地补充这些操作数,权限变更仍要确认。
  4. 提示 src/cli/protected-path-prompt.ts:第一行写明操作、路径原文、原因;选项最多三个(允许这一次 / 拒绝 / 本会话同一路径都允许);默认选中拒绝,回车不放行。中英文都有。
  5. 闸门位置 src/cli/approval.ts:在 resolvePermissionDecision 之后、ask 之前;deny / block 规则仍优先(只能更严,不放宽)。
  6. 护栏:读 .git/ 不拦;git commit / checkout / stash 等 git 自己写 .git/ 不拦;普通 src/ / test/ 编辑不问。

默认 full 模式未改宽。 只在受保护路径上收紧。

Base

基于最新 drobotics/main(含 O97 合并 cfd720ce)。Grok 草稿基于 #92 head 937a2581;合入时 patch 干净应用。中间态占位 shell-write-targets.ts 已删除,策略只消费 O97 的 detectShellWriteTargets。

Known limitations(必须诚实)

  • 间接脚本写(python fix.py、npm run x、make):detector 标 uncertain 但不点名受保护路径 → 不提示。约定行为,不是 bug。
  • 运行时拼路径(变量拼接、base64、命令替换结果)→ 拦不住。
  • $HOME 字面量:O97 detector 不展开;靠策略侧 basename / 路径段 / 文本正则兜底。
  • PowerShell 嵌套 / 编码命令:标 uncertain;只有命令文本 / mentions 提到受保护名才确认。
  • Shell 这一层是尽力拦截,不是沙箱。

Tests

跑法 结果
O94 新测试(有修复) 70 过 / 0 失败
O94 新测试(撤掉 O94 策略层,保留 O97 detector) 26 过 / 44 红(Grok 在换模块后实测;仍绿的是护栏 + 负例 + detector shape)
npm run check(format + lint + typecheck) 通过(Node 22.16.0)
全量 npm test(Node 22.16.0) 350 files passed / 0 fail

Revert-red(撤 O94 策略、保留 O97 detector)

撤掉后仍绿约 26 条:git commit/checkout/stash、读 .git、改 src//test/、.envrc.example、O90 风格 0 提示、python script.py 不问、detector-shape 等护栏 / 负例。其余 44 条变红,覆盖受保护路径确认与 -p 拒绝。

UX gate(待签)

按合门:正常做一单 O90 风格任务,全程确认提示 0 次。本 PR 有对应护栏单测(O90-style task flow → 0 prompts);端到端 UX 实测由 Moss UX 在 PR head 上跑完再签。

QA 合门提醒

  • 默认 full 模式不能改宽(只对受保护路径更严)
  • 读不拦;git 自己写 .git/ 不拦
  • 被拒后不能再用 shell / node -e 写同一受保护路径(与 O97 同一判法)
  • 合前请再按上次 6 条做安全复审

安全边界说明

shell 层受保护路径检测是尽力拦截,不是沙箱:只识别命令行里能静态解析的写入目标;经脚本间接写入(python x.py / node script.js / bash x.sh)不在覆盖范围,跟踪于 O101(P2)。

Writing/deleting/moving .git, .ssh, shell rc, .env, or Moss config always
asks once in interactive full mode and is denied in -p. Shell write
targets come from O97 detectShellWriteTargets; chmod/chown/chgrp are an
O94-only supplement. Default full mode is unchanged for normal paths.
Reads and git's own .git writes are not gated.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

QiaolongLi1201 added a commit that referenced this pull request Oct 11, 2026
Roadmap v1.1: fork's 11 draft PRs all concluded; upstream campaign PRs
#76-#92 merged (O13/O43/O57-58/O66-67/O70/O83/O85-88/O90/O97); npm first
release @rdk-moss/agent@0.26.1 live (rolling policy supersedes P4 gate,
remaining obligations folded into P2/P3); in-flight O94 (#93), O98 (#94),
SDK draft #68. AGENTS.md package name fixed to @rdk-moss/agent.
QA BLOCK on #93: approval only took the headless deny path when
!stdin.isTTY, so moss -p on a real terminal fell through to
defaultAskUser and hung. Detect print mode from the printMode option
(wired from parsedArgs.print) or argv -p/--print, and deny immediately.

Also: rm maps to delete/「删除」 in the protected-path prompt; startup
full-mode banner no longer says "no approval prompts" (protected paths
still ask once). Exit code after deny stays with O98.

Tests: TTY+printMode and TTY+argv -p regressions with 2s hang timeout;
rm label; locale banner assertions updated.
@QiaolongLi1201
QiaolongLi1201 merged commit 58c9e3d into main Oct 11, 2026
8 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant