Skip to content

[hooks] stop block-read-outside-cwd false-deny on globs and mounts#230

Merged
NiveditJain merged 2 commits into
mainfrom
luv-hooks-extract-paths-fix
Apr 29, 2026
Merged

[hooks] stop block-read-outside-cwd false-deny on globs and mounts#230
NiveditJain merged 2 commits into
mainfrom
luv-hooks-extract-paths-fix

Conversation

@NiveditJain
Copy link
Copy Markdown
Member

Summary

  • extractAbsolutePaths (src/hooks/builtin-policies.ts) used a negative lookbehind that only excluded identifier-ish chars, so a / after a glob meta or a compound-token separator was treated as the start of a fresh absolute path. Two common shapes were misread:
    • grep -rn 'Tab title=' docs/*/dashboard.mdx | head -30 → extracted /dashboard.mdx, then resolved outside cwd → deny.
    • docker run -v /home/user/project/docs:/docs node:20 ls /docs → extracted /docs (the container path) → deny.
  • Add *?:= to the lookbehind exclusion class so a / that immediately follows a glob meta or a separator does not start a match. Quoted paths, whitespace-separated absolute paths, and the ~/.claude/ whitelist all keep their existing behaviour.
  • 5 new regression tests in __tests__/hooks/block-read-outside-cwd.test.ts cover unquoted * and ? globs, the volume-mount shape, env-var-prefixed paths, and a still-denies case where a real outside read sits next to a glob. All 1083 unit tests pass; lint is clean.

Test plan

  • bun run test:run __tests__/hooks/block-read-outside-cwd.test.ts — 54 passed
  • bun run test:run — 1083 passed
  • bun run lint — clean (only an unrelated <img> warning)
  • Reproduce the original false-deny by running grep -rn 'Tab title=' docs/*/dashboard.mdx | head -30 in a session with this policy enabled — expect allow

🤖 Generated with Claude Code

extractAbsolutePaths used a negative lookbehind that only excluded
identifier-ish chars, so a slash after a glob meta or a compound-token
separator was treated as the start of a fresh absolute path. Two
common shapes were misread, e.g. an unquoted shell-glob argument and
a docker -v style host-to-container mount: in both cases the regex
extracted a fake absolute path that resolved outside cwd and got
denied even though the user was reading inside the project (or not
reading the host path at all, in the mount case). Add the chars
star, question, colon, equals to the lookbehind exclusion class so
a slash that immediately follows a glob meta or a separator does
not start a match. Quoted paths, whitespace-separated absolute
paths, and the home-claude whitelist all keep their existing
behaviour.

Five regression tests cover the new shapes plus a still-denies case
where a real outside read sits next to a glob.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 29, 2026

Warning

Rate limit exceeded

@NiveditJain has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 24 minutes and 10 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 43344a82-5823-4e4f-a71f-19b6176d03ef

📥 Commits

Reviewing files that changed from the base of the PR and between 11147a8 and cffba9c.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • __tests__/hooks/block-read-outside-cwd.test.ts
  • src/hooks/builtin-policies.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch luv-hooks-extract-paths-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 24 minutes and 10 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@NiveditJain NiveditJain merged commit 84a0652 into main Apr 29, 2026
9 checks passed
NiveditJain added a commit that referenced this pull request Apr 29, 2026
Per CodeRabbit feedback on #231: each CHANGELOG entry should be a single
line ending in its PR number. Tag mintlify-de and block-read-outside-cwd
fixes with their actual merged PRs (#229, #230) instead of #231.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
NiveditJain added a commit that referenced this pull request Apr 29, 2026
* [hooks] decouple hook chain from clsx/tailwind

The hook handler (`src/hooks/handler.ts`) was transitively pulling in
`lib/utils.ts` via:

  handler.ts
    -> resolve-permission-mode.ts
      -> lib/codex-sessions.ts
        -> lib/log-entries.ts
          -> lib/utils.ts (imports clsx + tailwind-merge)

`lib/utils.ts` is the dashboard's shadcn `cn()` helper — it has no business
on the runtime path of a CLI hook. The only thing the hook chain actually
needed from it was `formatDate`, an `Intl.DateTimeFormat` wrapper with no
third-party deps.

When a Claude Code session opened a clone of this repo whose
`$CLAUDE_PROJECT_DIR` resolved into an ancestor that shadowed bun's global
install cache (e.g. `/home/nivedit/prs/failproofai-231/`, with `node_modules`
missing locally but `/home/nivedit/node_modules` present and clsx-less),
every hook event crashed with:

  ResolveMessage: Cannot find package 'clsx' from .../lib/utils.ts

Move `formatDate` into a dedicated `lib/format-date.ts` and update the four
server-side and three dashboard callers. `lib/utils.ts` now only exports
`cn` so the hook handler no longer transitively requires `clsx`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* [changelog] condense unreleased entries to one-liners

Per CodeRabbit feedback on #231: each CHANGELOG entry should be a single
line ending in its PR number. Tag mintlify-de and block-read-outside-cwd
fixes with their actual merged PRs (#229, #230) instead of #231.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
NiveditJain added a commit that referenced this pull request Apr 29, 2026
Bumps package.json from 0.0.9 to 0.0.9-beta.2 and rolls the ## Unreleased
changelog section into ## 0.0.9 — 2026-04-28.

Adds since v0.0.9-beta.1:

Features:
- Show OpenAI Codex projects on the /projects page alongside Claude Code
  projects, with CLI badges per row and per session; /project/[name] is
  Codex-aware and the session viewer renders the CLI badge beside the
  Session Log header (#232)

Fixes:
- mintlify validate parse error in docs/de/dashboard.mdx (#229)
- block-read-outside-cwd false-deny on globs and -v host:/path (#230)
- decouple hook chain from clsx/tailwind via lib/format-date.ts (#231)

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
NiveditJain added a commit that referenced this pull request Apr 29, 2026
Promotes the version from 0.0.9-beta.3 to 0.0.9 stable. The
## 0.0.9 — 2026-04-28 changelog section is already up to date with the
contents below; no CHANGELOG churn required.

0.0.9 contents:

Features:
- OpenAI Codex hook integration via `failproofai policies --install --cli codex`
  (or --cli claude codex for both); supports all six Codex hook events,
  PermissionRequest wired through policy-evaluator, per-CLI telemetry tagging,
  interactive arrow-key CLI selector when both agents detected (#220, #222, #223)
- Activity dashboard CLI filter alongside event-type, policy, and session-id
  filters; Codex sessions in the activity feed are now clickable, with the
  existing log viewer rendering Codex transcripts via lib/codex-sessions.ts (#226)
- Surface Slack community link in CLI banner and Reach Us menu (#225)
- Show OpenAI Codex projects on the /projects page alongside Claude Code projects,
  with CLI badges per row and per session; /project/[name] is Codex-aware and the
  session viewer renders the CLI badge beside the Session Log header (#232)

Fixes:
- Trailing blank line after enabled-policies summary in install output (#224)
- Resolve hook bin via $CLAUDE_PROJECT_DIR (was relative path) (#219)
- Mintlify validation of Arabic built-in-policies docs
- Mintlify parse error in docs/de/dashboard.mdx (#229)
- block-read-outside-cwd false-deny on globs and -v host:/path (#230)
- Decouple hook chain from clsx/tailwind via lib/format-date.ts (#231)

Docs:
- Bump built-in policy count from 32 to 39 in README and translations (#207)

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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