Skip to content

fix(security): a cd in a pipeline or background job does not move the scrub hook into the tracker - #1915

Merged
potiuk merged 2 commits into
apache:mainfrom
potiuk:scrub-pipeline-cd
Oct 30, 2026
Merged

potiuk merged 2 commits into
apache:mainfrom
potiuk:scrub-pipeline-cd

Conversation

@potiuk

@potiuk potiuk commented Oct 30, 2026

Copy link
Copy Markdown
Member

The public-surface scrub hook skipped a cd for directory tracking only when the separator after it was | or &.
That catches a cd that starts a pipeline, but not one in a later stage:

echo x | cd /path/to/tracker; gh issue create -t "..." -b "..."

Bash runs that cd in a subshell, so the shell stays in the upstream clone,
but the hook moved its tracked directory to the tracker and gave the bare gh the tracker exemption, skipping the scrub.
A cd inside a brace group in a pipeline did the same, whether the group came after the pipe (echo x | { true; cd /tracker; })
or was itself piped or backgrounded ({ cd /tracker; true; } | cat, where the | sits only on the group's last command).

Once a | or & has appeared on the line, any cd now marks the line as redirected,
and the splitter marks every command of a piped or backgrounded brace group so its cd does too;
a later bare git or gh then loses the cwd exemption.
This is the fail-closed rule the hook already applies to a cd after && or ||.

Tests: a new case in the per-path fixture (start upstream, piped cd into the tracker, bare gh / git commit must be scanned, four shapes),
and four shapes added to the redirect list.
Both fail on main and pass with the fix; the whole mod suite passes (tools/dev/check-claude-mods.sh --local).

Found by an automated security review of the hook after #1914.


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Claude Opus 5)

Generated-by: Claude Code (Claude Opus 5) following the guidelines

🤖 Generated with Claude Code

The scrub hook skipped a `cd` for directory tracking only when the
separator after it was `|` or `&`, which catches a `cd` that starts a
pipeline but not one in a later stage. In `echo x | cd /tracker; gh issue
create ...` the `cd` runs in a subshell and the shell stays in the
upstream clone, but the hook moved its tracked directory to the tracker
and exempted the bare `gh` from the scrub. The same held for a `cd` inside
a brace group in a pipeline.

Once a `|` or `&` has appeared on the line, any `cd` now marks the line
as redirected, so a later bare git or gh command loses the cwd exemption,
the same fail-closed rule the hook applies to a `cd` after `&&` or `||`.

Generated-by: Claude Opus 5
… redirect

In `{ cd /tracker; true; } | cat` the group is the first pipeline stage, so
its inner `cd` ends with `;` and the `|` sits only on the group's last
command. The splitter now marks every command of a brace group that is
piped or backgrounded, and such a `cd` removes the cwd exemption.

Generated-by: Claude Opus 5
@potiuk
potiuk enabled auto-merge (squash) October 30, 2026 19:26
@github-actions github-actions Bot added the family:security security-* skills label Oct 30, 2026
@potiuk
potiuk merged commit f0481de into apache:main Oct 30, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

family:security security-* skills

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant