fix(exec-policy): accept trusted ~/.openclaw symlink at home boundary#72650
fix(exec-policy): accept trusted ~/.openclaw symlink at home boundary#72650Bojun-Vvibe wants to merge 3 commits into
Conversation
Greptile SummaryThis PR allows a symlinked Confidence Score: 4/5Safe to merge; both findings are P2 and the core security logic is sound. The trusted-hop check correctly enforces ownership and mode before following a symlink, and deeper symlinks remain rejected. Two P2 concerns: (1) the src/infra/exec-approvals.ts — the
|
f8eb14f to
caced25
Compare
The exec-approvals symlink hardening from openclaw#72377 still rejected a symlinked ~/.openclaw immediate child of the trusted home directory, breaking exec-policy commands for users who manage OpenClaw config via GNU Stow, chezmoi, or other dotfile managers. openclaw#72377 only relaxed the restriction on the OPENCLAW_HOME root itself. Allow exactly one trusted symlink hop at the immediate child of the trusted home root, but only when the realpath target is owned by the current effective user AND is not group/other writable. Deeper symlinks inside the resolved .openclaw tree, additional symlink hops, and unsafe-permission targets remain rejected with the original error message. Updates the existing 'refuses to traverse symlinked approvals components below a symlinked home' test to construct an unsafe target (group-writable) so the deeper-symlink rejection intent of openclaw#72377 is still exercised, and adds a new test for the safe-symlink case from this issue. Fixes openclaw#72572 Refines openclaw#72377, openclaw#64663, openclaw#64050
254e1ea to
3bb8640
Compare
Greptile review on openclaw#72572: the flag was logically dead — it can only be set when i === 0, and the loop never revisits i === 0, so by the time it could be true, !isImmediateRootChild is already true. Removing it makes the at-most-one-hop invariant rest visibly on the !isImmediateRootChild guard. Behavior is unchanged; existing tests still cover the single-hop allow, double-hop reject, and untrusted-target reject paths.
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as superseded: the underlying symlinked Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Canonical path: Keep #72572 open and land one rebased, security-reviewed fix against the current So I’m closing this here and keeping the remaining discussion on #72572. Review detailsBest possible solution: Keep #72572 open and land one rebased, security-reviewed fix against the current Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows Is this the best way to solve the issue? No. The compatibility direction is valid, but this branch is not the best current fix because it targets the removed local path walker, lacks real behavior proof, and needs a security-reviewed current-main implementation. Security review: Security review needs attention: The patch changes command-approval filesystem trust boundaries and is stale against the current fs-safe/chmod implementation.
AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 010b61746379. |
|
ClawSweeper PR egg 🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat. Where did the egg go?
|
|
This pull request has been automatically marked as stale due to inactivity. |
Fixes #72572.
Problem
The exec-approvals symlink hardening from #72377 only relaxed the restriction on the
OPENCLAW_HOMEroot itself, so a symlinked~/.openclawimmediate child of a real home directory still tripsassertNoSymlinkPathComponents():```
Refusing to traverse symlink in exec approvals path: /Users/funjim/.openclaw
```
This breaks `openclaw exec-policy preset yolo` (and every other exec-policy command) for users who manage their OpenClaw config via GNU Stow, chezmoi, or any other dotfile-managed setup that exposes `~/.openclaw → ~/dotfiles/openclaw/.openclaw`.
Fix
Allow EXACTLY ONE trusted symlink hop at the immediate child of the trusted home root, gated by the same hardening intent as #64050 / #72377:
Permissive on platforms without `process.geteuid` (Windows), where the OS ACL model already differs.
`ensureDir()` is taught to accept a `dir` whose `lstatSync` reports a symlink, but only after re-asserting the realpath target is a directory — `assertNoSymlinkPathComponents()` already vetted ownership/perms.
Tests
All 18 `exec-approvals-store` tests pass; `pnpm tsgo:test` clean.
Diff
+92 / -3 across 2 production files + 1 test file + CHANGELOG.
Refs