Repository navigation
#657 [security][tools] Bash と検証コマンドの、home の秘密の場所の読み取りを OS の隔離で拒否する(第 2 段) - #670
Merged
Merged
Conversation
Issue #657 (stage 2 of #502) adds an OS read-confinement layer to the #655/#656 write backend: - A shared leaf (src/tools/os_sandbox/secret_locations.rs) holds the home secret list, the #501 workspace credential basenames, and the three #501 path sequences; both backends import it. - macOS Seatbelt denies the home secret locations (subpath params) and the workspace credentials (case-folded regex with a `(/.*)?$` tail so a credential-named directory's contents are denied); a later rule re-allows the strict dotenv templates and a final rule re-denies a template below a credential directory. The regex root is canonicalized. - Linux Landlock handles the read rights (`Execute | ReadFile | ReadDir`, from ABI1) and rewrites the deny list into a read-allow list built once at run start. It canonicalizes each secret location (so a symlinked `~/.ssh` denies its target) and the writable locations (so a symlinked workspace is compared by its real path), and reports in `bash_sandbox_status` when a writable location is the home, an ancestor of a secret, or inside a secret (or when HOME is empty), instead of claiming the read isolation applied. - The read-allow expansion skips symlink entries: `path_beneath_rules` opens a path with `O_PATH`, following the link, so a rule for a symlink entry would attach to its target. A sibling symlink to a secret file, or a secret location that is itself a link, would otherwise open the secret; the real path decides those instead. - The availability probe builds its own write-only ruleset (no allow rules), so its child can still `exec` even though the production ruleset now handles the read set. - The read isolation is reported through the existing `bash_sandbox_status` reason (no new event field, no name/field change). - Docs: SECURITY.md and both cli-reference files describe the read layer, the Linux ReadDir consequence (`ls /`, `ls $HOME`, `echo $HOME/*`), and the home-npm-config consequence. - Tests (added for cargo-mutants gaps): a unit test pins `SandboxPolicy::new(..).home` to the process `HOME` (so emptying `home_dir` is caught), and the workspace-regex test now checks the rule is anchored at the canonical workspace root via the `regex` crate (so emptying `escape_regex`, which would deny the name everywhere, is caught). 読み替え: 本文の受入条件は bash_sandbox_status へ field を足す形を示唆しますが、 tests/issue502_os_sandbox_write.rs が applied + ABI3+ で reason==None、unavailable で reason==プローブ理由、を厳密に固定しており(そのまま通すことが制約)、新しい field を 足すと書き込み隔離の証跡を書き換えることになります。指示に従い、field ではなく既存の reason で読み取りの隔離の適用・未適用を報告しています。 判断: 読み取りは書き込みと同じ backend 可用性で適用されるため、Linux の ABI3+ かつ 完全に閉じている場合は reason を None(=完全に隔離)に保ち、未適用(writable が secret を 覆う場合・secret の中の場合・HOME が空の場合)と ABI<3 の場合に reason を出します。 macOS は write limitation が無いため reason に "read isolation applied" を出します。 Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Match the Read confinement item to the actual behavior: denial is decided by name and path, so on macOS a credential renamed or copied to another name inside the writable workspace is not denied, and a name an interpreter assembles at run time is closed only when the assembled name is itself a denied name. Note that a secret reached from an off-list path through a bind mount, or through a hardlink created outside the isolation, is not denied on either OS, while creating such a hardlink inside the isolation is. Also state that the Linux read-allow list is rebuilt at each command's start (not once at run start), so a location created after a command starts is not readable inside that command. Fix the same sentences in the en and ja cli-reference files. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
12 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
#502 の第 2 段(読み取り隔離)です。Bash と検証コマンドから、home の秘密の場所の読み取りを OS の隔離で拒否します。拒否リスト型で、macOS は Seatbelt の
deny file-read*、Linux は拒否リストを landlock の許可リストに展開します。home の npm の設定も拒否します(設計は 2026-10-11 に承認)。Refs #657
変更(develop 比 11 ファイル、+2001 −114、2 commit)
src/tools/os_sandbox/secret_locations.rs、新規の葉モジュール)~/.ssh・~/.aws・~/.gnupg・~/.netrc・~/.git-credentials・~/.npmrc・~/.pypirc・~/.docker/config.json・~/.kube・~/.config/gh・~/.config/gcloud。sensitive_name_ruleとpath_ruleに揃えています。seatbelt.rs):home の場所は(deny file-read* (subpath …))で、ワークスペースの規則は正規表現で拒否します。場所はすべて-Dの param で渡し、profile の文字列には入れません。landlock.rs)from_allにしました。拒否リストは、各コマンドの起動時に許可リストへ展開します。os_sandbox.rs):読み取りの隔離の状態は、bash_sandbox_statusの既存のreasonで出します。event の名前と field は変えていません(src/lib.rsの diff は空です)。read isolation appliedread isolation is not effective …。書き込みの場所が秘密と重なるとき、HOME が空のとき、policy が無いときです。SandboxPolicy::with_homeで、HOME を tempdir に向けます。SECURITY.mdと ja・en の cli-reference。tests/issue502_os_sandbox_read.rs(新規)と corpustests/corpus/apps/issue502-indirect-read/。偽の鍵だけを使い、HOME は tempdir です。bash.rs・bash_write_guard.rs・sensitive_path.rs)src/lib.rs、成長上限のファイルと baselineCargo.toml・Cargo.lock・deny.toml・.github/workflows/ci.ymltests/issue502_os_sandbox_write.rs検証
dac61997でcommandmate verifyが 15/15 passed でした。最終 commit の後に流し、worktree は clean です。cargo deny check:exit 0(advisories・bans・licenses・sources とも ok)。cargo-zigbuild clippy --all-targets --target x86_64-unknown-linux-gnuは exit 0 です。--include-ignored):読み取り 10/10、書き込み 18/18、SKIP 0。required、偽の home)で次を確かめました。--version(cargo・rustc・node・npm・python3・git)、依存のない crate のcargo build、キャッシュ済みの fixture のnpm ci~/.npmrc、外へのtouchCI=trueで、読み取り 12/12、書き込み 17/17 です。BASH_ENV、python が組み立てた名前、.npmrc--version、cargo build、npm ci、next buildCIがあるときは、landlock が未適用か ABI が足りなければ試験が失敗します。kernel と ABI は job summary に 1 行書きます。--jobs 1、--timeout 300)home_dirを空にする変異)。試験を足し、取り直して caught です。レビュー
..・/proc/self/root・hardlink・symlink の dir・cp・O_PATH の開き直しです。dac61997)は文書だけです。H-28 の推奨に沿って、限界を実際どおりに書きました。文書に明記した限界
ls /・ls $HOME・echo $HOME/*)はできません。~/.npmrcを使うnpmは、Bash の中で失敗します。後続の論点
reasonがNone:macOS はread isolation applied、未適用・効かないときは両 OS とも理由の文です。明示の文に揃えるにはtests/issue502_os_sandbox_write.rsの期待を変えるので、後続の小さな Issue を推奨します。requiredの run での実績を見て、トークンを Bash の外から渡す方法を検討します。CI の runner の kernel と ABI
dac61997)では、issue502_os_sandbox_readは 10 passed・2 ignored でした(ignored は heavy の 2 本で、CI では明示しないと走りません)。CIがあるので、landlock が未適用か ABI が足りなければ、この試験は失敗します。通ったので、runner で読み取りの隔離は適用されていました。issue502/657 landlock read: kernel=… abi=…)は job summary にだけ書かれます。job summary はghと API では取れないため、ここには記録できていません(ログには出ません。cargo testが通った試験の出力を捕まえるため)。kernel=6.17.0-1022-azure abi=7です。🤖 Generated with Claude Code