Repository navigation
security(step): refuse check_diff patches that write inside .git - #1585
Conversation
…e state dir private Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 7 minutes. View limit detailsLimit details: You’ve used all 4 included reviews currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (7)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (7)
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe change adds restricted-permission creation for state-directory paths and uses it for patches, logs, and output files. It also rejects patch operations that target Git’s internal directory and adds regression tests for both changes. ChangesState directory permissions
Git-internal patch path protection
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix Merge Risk: ⚪ Minimal · up to The change makes hk's state directory private on Unix and refuses patches that write inside .git. No merge-blocking risk was identified from the supplied evidence. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The changes strengthen filesystem protections without expanding privileges. No introduced security regression was identified in the reviewed code. Existing directory permissions and crash-recovery limitations remain unchanged; cross-platform validation remains limited. Retained concerns Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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. Comment |
|
Instruction countsNothing was compared, and so nothing was gated. No series appears on both sides: either the base has no measurements recorded, or the two were measured on different runner classes, which are deliberately not comparable — counts shift between machine types by more than a real regression does. New, nothing to compare against: Only instruction counts gate. Wall clock is shown for context — on identical hardware it moves 4-20% run to run. Measured by tak — instruction-counted CLI benchmarks, stored in this repository's git notes.
|
Merges main. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
<!-- entire-trail-link-start --> https://entire.io/gh/jdx/hk/trails/116 <!-- entire-trail-link-end --> ### 🚀 Features - **(builtins)** keep CRLF files CRLF in trailing_whitespace, newlines, and mixed_line_ending by [@jdx](https://github.com/jdx) in [#1621](#1621) - **(builtins)** report revive findings as diagnostics by [@jdx](https://github.com/jdx) in [#1626](#1626) - **(builtins)** report buf_lint and clang_format findings as diagnostics by [@jdx](https://github.com/jdx) in [#1627](#1627) - **(builtins)** report actionlint findings as diagnostics by [@jdx](https://github.com/jdx) in [#1623](#1623) - **(builtins)** report flake8 findings as diagnostics by [@jdx](https://github.com/jdx) in [#1624](#1624) - **(builtins)** report mypy, mado and six more linters as diagnostics by [@jdx](https://github.com/jdx) in [#1630](#1630) - **(config)** read column-less, prefixed and summarized output with the gcc diagnostic format by [@jdx](https://github.com/jdx) in [#1629](#1629) - **(init)** detect 47 more tools from their config files by [@jdx](https://github.com/jdx) in [#1576](#1576) - **(mcp)** let agents run checks on changed or unstaged files only by [@jdx](https://github.com/jdx) in [#1600](#1600) - **(mcp)** let agents run checks on staged files only by [@jdx](https://github.com/jdx) in [#1640](#1640) - **(test)** assert normalized diagnostics in step tests by [@jdx](https://github.com/jdx) in [#1622](#1622) - **(validate)** warn about misspelled properties, no-op depends, unmatchable globs and loose min_hk_version by [@jdx](https://github.com/jdx) in [#1590](#1590) ### 🐛 Bug Fixes - **(agent)** make --safe refuse a hook report with unknown or destructive effect by [@jdx](https://github.com/jdx) in [#1573](#1573) - **(agent)** make Claude Code and Codex Stop hooks block with a valid decision and exit 0 by [@jdx](https://github.com/jdx) in [#1604](#1604) - **(builtins)** check large files and case conflicts in binary files by [@jdx](https://github.com/jdx) in [#1571](#1571) - **(check)** fail on unknown --step names instead of passing after running no steps by [@jdx](https://github.com/jdx) in [#1603](#1603) - **(ci)** fail test:bats on a mistyped path or when no tests run by [@jdx](https://github.com/jdx) in [#1563](#1563) - **(cli)** keep generated output exit codes on closed pipes by [@jdx](https://github.com/jdx) in [#1540](#1540) - **(cli)** print failures once, without Rust locations or a bogus fix hint by [@jdx](https://github.com/jdx) in [#1588](#1588) - **(config)** union user skip_steps, skip_hooks and hide_warnings with the project's, and warn when hk.local.pkl replaces hk.pkl by [@jdx](https://github.com/jdx) in [#1596](#1596) - **(config)** honor top-level jobs, accept documented HK_STASH values, and fix the hk config crash by [@jdx](https://github.com/jdx) in [#1594](#1594) - **(config)** honor subproject skip_steps and warn about ignored subproject settings by [@jdx](https://github.com/jdx) in [#1615](#1615) - **(docs)** stop sidebar links showing through the logo when it bounces by [@jdx](https://github.com/jdx) in [#1554](#1554) - **(git)** skip tracked files with non-UTF-8 names with a warning in --all, --glob, --from-ref and file arguments by [@jdx](https://github.com/jdx) in [#1613](#1613) - **(init)** explain why a hook is missing and print next steps after hk init by [@jdx](https://github.com/jdx) in [#1564](#1564) - **(install)** correct the --force-local message when a global install exists by [@jdx](https://github.com/jdx) in [#1616](#1616) - **(install)** keep hook commands working after hk upgrades and under a minimal PATH by [@jdx](https://github.com/jdx) in [#1597](#1597) - **(mcp)** make cancel_run stop the real hk run instead of sticking in cancelling by [@jdx](https://github.com/jdx) in [#1607](#1607) - **(mcp)** cap step output in structured results and report pre-run failures by [@jdx](https://github.com/jdx) in [#1605](#1605) - **(mcp)** include untracked and binary files in get_diff and surface capture errors by [@jdx](https://github.com/jdx) in [#1601](#1601) - **(pkl)** load configs that amend the v1 package schema by [@jdx](https://github.com/jdx) in [#1560](#1560) - **(pkl)** hide mirror credentials in failed package download errors by [@jdx](https://github.com/jdx) in [#1620](#1620) - **(pkl)** show file, line and column for Pkl syntax errors, including in imported files by [@jdx](https://github.com/jdx) in [#1598](#1598) - **(stash)** preserve CRLF when restoring unstaged files by [@jdx](https://github.com/jdx) in [#1535](#1535) - **(stash)** restore unstaged text over a staged binary file no step changed by [@jdx](https://github.com/jdx) in [#1580](#1580) - **(stash)** stash tracked files whose names start with a colon by [@jdx](https://github.com/jdx) in [#1614](#1614) - **(stash)** keep a staged edit when its worktree copy was reverted to HEAD by [@jdx](https://github.com/jdx) in [#1602](#1602) - **(stash)** keep a merge or cherry-pick in progress when stashing the worktree by [@jdx](https://github.com/jdx) in [#1609](#1609) - **(stash)** restore hk's own stash entry by commit id so concurrent stashes are never touched by [@jdx](https://github.com/jdx) in [#1637](#1637) - **(stash)** serialize stash and restore across hk processes and linked worktrees by [@jdx](https://github.com/jdx) in [#1636](#1636) - **(stash)** restore stashed changes when hk is terminated and recover them after a crash by [@jdx](https://github.com/jdx) in [#1641](#1641) - **(step)** isolate formatter patches from concurrent commands and staging by [@nettlesh](https://github.com/nettlesh) in [#1392](#1392) - **(step)** keep interactive steps in hk's process group by [@jdx](https://github.com/jdx) in [#1557](#1557) - **(step)** say "command not found" when an argv step's tool is not installed by [@jdx](https://github.com/jdx) in [#1579](#1579) - **(step)** add exec_ok for condition shell tests and stop exec panicking by [@jdx](https://github.com/jdx) in [#1610](#1610) - **(step)** run steps that depend on a step with no files instead of hanging by [@jdx](https://github.com/jdx) in [#1584](#1584) - **(step)** select files in directories whose names contain brackets or braces by [@jdx](https://github.com/jdx) in [#1592](#1592) - **(step)** keep percent signs in file names literal under cmd.exe by [@jdx](https://github.com/jdx) in [#1568](#1568) - **(step)** end tools left running by a fail-fast cancel on Windows by [@jdx](https://github.com/jdx) in [#1625](#1625) - **(step)** exclude a directory's files when a step or group exclude names it by [@jdx](https://github.com/jdx) in [#1606](#1606) - **(step)** report diagnostic paths relative to the repository root for steps that run in a subdirectory by [@jdx](https://github.com/jdx) in [#1638](#1638) - **(step)** run a custom shell directly on Windows and accept a quoted shell path by [@jdx](https://github.com/jdx) in [#1628](#1628) - **(step)** batch Windows cmd shims below the cmd.exe line limit by [@jdx](https://github.com/jdx) in [#1618](#1618) - **(step)** type scripts whose env shebang has -S, options or variables by [@jdx](https://github.com/jdx) in [#1611](#1611) - **(step)** keep diagnostics from every started job when another job fails by [@jdx](https://github.com/jdx) in [#1642](#1642) - **(step)** report steps stopped by Ctrl-C as cancelled instead of failed by [@jdx](https://github.com/jdx) in [#1643](#1643) - **(util)** check files whose 8 KiB probe splits a multibyte char and keys in non-UTF-8 files by [@jdx](https://github.com/jdx) in [#1572](#1572) - **(util)** accept git-generated merge and revert titles in check-conventional-commit by [@jdx](https://github.com/jdx) in [#1566](#1566) - **(util)** check protected branch, exec bits and case conflicts against git's own state by [@jdx](https://github.com/jdx) in [#1577](#1577) - **(util)** keep non-UTF-8 files and symlinks intact in fix-smart-quotes by [@jdx](https://github.com/jdx) in [#1570](#1570) - **(validate)** reject dependency cycles, self-dependencies and invalid step globs at load time by [@jdx](https://github.com/jdx) in [#1567](#1567) ### 📚 Documentation - **(builtins)** show file selectors, script commands and options in the catalogue by [@jdx](https://github.com/jdx) in [#1562](#1562) - **(config)** explain where diagnostics come from and when a step needs diagnostic_format by [@jdx](https://github.com/jdx) in [#1619](#1619) - **(config)** document sharing one configuration across repositories by [@jdx](https://github.com/jdx) in [#1591](#1591) - **(settings)** describe pkl rewrite and CA variables for the built-in evaluator by [@jdx](https://github.com/jdx) in [#1617](#1617) - refresh competitor benchmark for v2.4.0 by [@jdx](https://github.com/jdx) in [#1536](#1536) - replace the sea shanty with Bound for the Main and its music video by [@jdx](https://github.com/jdx) in [#1541](#1541) - take the new shanty video down if its poster cannot be published by [@jdx](https://github.com/jdx) in [#1543](#1543) - add a sea shanty mode to the landing page by [@jdx](https://github.com/jdx) in [#1544](#1544) - keep a link to the sea shanty when scripting is off by [@jdx](https://github.com/jdx) in [#1545](#1545) - generate the pirate CLI reference from the English one by [@jdx](https://github.com/jdx) in [#1550](#1550) - restrict AI replies on Discussions and Issues and note the instant ban by [@jdx](https://github.com/jdx) in [#1559](#1559) - start getting started with a first configuration that needs no linters by [@jdx](https://github.com/jdx) in [#1561](#1561) - correct stash, type-checker lock, and patch-apply descriptions by [@jdx](https://github.com/jdx) in [#1578](#1578) - add lefthook and husky with lint-staged migration guides by [@jdx](https://github.com/jdx) in [#1589](#1589) ### ⚡ Performance - **(config)** evaluate only the builtins a config uses, cutting cold load from ~1.4 s to ~0.07 s by [@jdx](https://github.com/jdx) in [#1581](#1581) - **(git)** skip the untracked scan for runs that name their files, e.g. hk check FILE by [@jdx](https://github.com/jdx) in [#1587](#1587) - **(stash)** restore unstaged files no step changed with one git process by [@jdx](https://github.com/jdx) in [#1612](#1612) - **(stash)** stop rescanning the worktree before stashing, saving ~80 ms on large repos by [@jdx](https://github.com/jdx) in [#1595](#1595) - **(step)** resolve workspace_indicator once per directory, saving ~120 ms per step in large monorepos by [@jdx](https://github.com/jdx) in [#1599](#1599) - **(step)** run read-only check-only steps side by side in fix hooks by [@jdx](https://github.com/jdx) in [#1586](#1586) - use mimalloc as the global allocator by [@jdx](https://github.com/jdx) in [#1635](#1635) - bump pklr to 4.0.0 (hk validate 14x faster) by [@jdx](https://github.com/jdx) in [#1644](#1644) ### 🧪 Testing - **(windows)** run every e2e-win case and cover fix, staging and installed hooks by [@jdx](https://github.com/jdx) in [#1574](#1574) - fix bats teardown and event-order flakes and surface CI retries by [@jdx](https://github.com/jdx) in [#1583](#1583) ### 🛡️ Security - **(deps)** update dependency esbuild to ^0.28.0 by [@renovate[bot]](https://github.com/renovate[bot]) in [#1548](#1548) - **(step)** refuse check_diff patches that write inside .git by [@jdx](https://github.com/jdx) in [#1585](#1585) - point the landing page at the sea shanty by [@jdx](https://github.com/jdx) in [#1542](#1542) - turn sea shanty mode into a pirate edition of the whole docs site by [@jdx](https://github.com/jdx) in [#1549](#1549) - document what hk executes, global hook reach, and --safe limits in a security model page by [@jdx](https://github.com/jdx) in [#1575](#1575) - bring the sea shanty contributing page up to date with the English page by [@jdx](https://github.com/jdx) in [#1631](#1631) ### 🔍 Other Changes - **(benchmark)** gate hook stashing and cold config loads in the perf check by [@jdx](https://github.com/jdx) in [#1608](#1608) - **(entire)** store checkpoints in a private repository by [@jdx](https://github.com/jdx) in [74bd981](74bd981) - **(entire)** commit codex session hooks by [@jdx](https://github.com/jdx) in [71966d2](71966d2) - **(entire)** commit claude session hooks by [@jdx](https://github.com/jdx) in [2298ebf](2298ebf) - **(entire)** store checkpoints in a private repository by [@jdx](https://github.com/jdx) in [4a4e806](4a4e806) - **(entire)** restore lower-cost trail findings by [@jdx](https://github.com/jdx) in [6eed674](6eed674) - **(install)** refuse legacy hook installs that overwrite foreign hooks or symlinks by [@jdx](https://github.com/jdx) in [#1593](#1593) - **(release)** smoke-run every release archive before the release is created by [@jdx](https://github.com/jdx) in [#1565](#1565) - **(security)** check RustSec advisories in CI and document gh release verify by [@jdx](https://github.com/jdx) in [#1569](#1569) - unblock the docs deploy and stop re-rendering unchanged videos by [@jdx](https://github.com/jdx) in [#1551](#1551) - limit each contributor to one open draft PR by [@jdx](https://github.com/jdx) in [#1555](#1555) - lint test code by running clippy with --all-targets by [@jdx](https://github.com/jdx) in [#1582](#1582) - combine hosted Bats configurations by [@jdx](https://github.com/jdx) in [#1633](#1633) - skip full checks for docs-only pull requests by [@jdx](https://github.com/jdx) in [#1634](#1634) - remove redundant package.homepage from Cargo.toml by [@jdx](https://github.com/jdx) in [#1639](#1639) ### 📦️ Dependency Updates - lock file maintenance by [@renovate[bot]](https://github.com/renovate[bot]) in [#1537](#1537) - update jdx crates by [@renovate[bot]](https://github.com/renovate[bot]) in [#1539](#1539) - update github actions by [@renovate[bot]](https://github.com/renovate[bot]) in [#1546](#1546) - update dependency aube to latest by [@renovate[bot]](https://github.com/renovate[bot]) in [#1547](#1547) - update dependency communique to latest by [@renovate[bot]](https://github.com/renovate[bot]) in [#1553](#1553) - update rust crate clx to v3.0.3 by [@renovate[bot]](https://github.com/renovate[bot]) in [#1552](#1552) - update dependency aube to latest by [@renovate[bot]](https://github.com/renovate[bot]) in [#1556](#1556) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Mechanical version and documentation URL updates plus changelog; no runtime code changes in the diff. > > **Overview** > **Release cut** that bumps the crate and CLI from **2.4.0** to **2.5.0** (`Cargo.toml`, `Cargo.lock`, `hk.usage.kdl`, generated CLI metadata) and adds the **[2.5.0] CHANGELOG** section dated 2026-10-04, cataloguing everything shipped since v2.4.0. > > Doc and sample configs are updated so `amends` / `import` examples point at `package://…/v2.5.0/hk@2.5.0` (README, getting started, migration guides, pirate docs, public `.pkl` examples, `hk-example.pkl`, and a commented line in `hk.pkl`). No application logic changes appear in this diff—only versioning and release notes alignment. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8d358e2. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: mise-en-dev <123107610+mise-en-dev@users.noreply.github.com>
https://entire.io/gh/jdx/hk/trails/162
When a step defines
check_diff, hk applies the patch it prints in-process instead of running the fixer. That applier (built ondiffy) accepted patches that name paths inside.git, whichgit applyrefuses. Acheck_difftool that printed (or was tricked into printing)+++ .git/hooks/post-commitcould therefore plant a hook that runs on the next commit, or edit.git/config.What changes
verify_path:.gitin any case, with trailing dots or spaces (.git.), NTFS alternate data streams (.git::$INDEX_ALLOCATION), the NTFS short namegit~1, and.gitwith HFS+-ignorable Unicode inserted. Both sides of a---/+++pair are checked, in any directory depth (sub/.git/config). Look-alikes such as.gitignoreand.githubstill apply.~/.local/state, are created as usual, and an existing state directory keeps its permissions.Before and after, with a
check_diffthat prints a patch creating.git/hooks/post-commitnext to a valid change:Validation
cargo test: 525 passed, 0 failed (new unit tests cover theis_dot_gitspellings, both-sides refusal, nothing written on refusal, and look-alikes still applying).test/apply_check_diff.bats: 41okof a 41-test plan, for both the libgit2 and no-libgit2 runs. The new test fails when the check is disabled (I temporarily disabled it to confirm) and passes with it.test/state_dir_permissions.bats(new): 1 of 1ok; the state directory isdrwx------and its parent keeps default permissions.scripts/validate-apple-pkl.pypasses.hk check --all: all steps pass exceptcargo-check, which fails on this machine because of existing manifest warnings (package.homepageredundant, unusedtracing-error) unrelated to this change.Limits
Existing state directories are not tightened. Windows has no 0700 equivalent here, and the
.gitchecks are written for all platforms but were only run on Linux. Other path-based risks, such as symlinks and hard links, were already refused before this change.AI-assisted — Tool: Claude Code; model: anthropic/claude-sonnet-5-5; version: unavailable.
🤖 Generated with Claude Code
Note
High Risk
Changes security-sensitive patch application and how locally stored hook output/stash data is created on disk; incorrect matching could block legitimate diffs or still allow
.gitwrites.Overview
Closes a gap where the in-process
check_diffpatch applier could write under.git(e.g. hooks) even thoughgit applywould reject those paths. Patches are now rejected before any write when any path component matches git’sverify_pathrules—case variants, trailing dots/spaces,git~1, NTFS stream suffixes, HFS ignorable Unicode, nested paths likesub/.git/config, and both---and+++sides on modify hunks. Look-alikes such as.gitignorestill apply; a refused patch behaves like a non-applicable patch (warning + fixer runs).Separately,
create_state_dir_allcreates directories underHK_STATE_DIRwith 0700 on Unix (logs, output, stash patch backups), while parents outside that tree and already-existing dirs are unchanged. Call sites for patches, log files, andHK_OUTPUT_FILEnow use this helper instead of plaincreate_dir_all.New unit, bats, and
state_dir_permissionstests cover.gitspellings, end-to-end fix behavior, and state-dir mode.Reviewed by Cursor Bugbot for commit f758bfd. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
.gitdirectory are now rejected, while similarly named paths such as.gitignoreremain valid.