mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-26 10:01:28 +08:00
fix(gateguard): check isDestructiveFindExec on each command segment to close compound-command bypass (#2292)
* fix(gateguard): check isDestructiveFindExec on each command segment
`isDestructiveBash` called `isDestructiveFindExec` only on the raw full
command string. When the raw string starts with a non-find command (e.g.
`echo x && find . -exec rm {} \;`), `isDestructiveFindExec` checks
tokens[0] and returns false — then the per-segment loop never calls it
again, letting the destructive `find -exec rm` segment through silently.
Fix: call `isDestructiveFindExec(segment)` inside the per-segment loop so
compound commands (`&&`, `;`, `|`) cannot be used to prepend a harmless
command and bypass the find-exec destructive check.
Adds three regression tests covering `&&`, `;`, and `|` bypass patterns.
* fix(gateguard): use raw body segments for isDestructiveFindExec to close quoted-binary gap
The previous per-segment call passed quote-stripped output from
splitCommandSegments to isDestructiveFindExec, so a quoted exec binary
like find . -exec 'rm' {} \; would arrive as find . -exec {} \; and
the check would silently miss it.
Switch to splitting collectExecutableBodies output on [;|&]+ without
quote-stripping first, so the find-exec binary name is always intact
when isDestructiveFindExec inspects it. This also covers || and
background & separators that the original tests did not exercise.
Adds a regression test for the || OR-chain bypass pattern.
Addresses Greptile review comments on PR #2292.
---------
Co-authored-by: kapilvus <kapilvus@gmail.com>
This commit is contained in:
@@ -1613,6 +1613,26 @@ function runTests() {
|
||||
'find -exec git reset --hard');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('denies find -exec rm {} \\; preceded by && (bypass via compound command)', () => {
|
||||
expectDestructiveDeny('echo x && find . -exec rm {} \\;',
|
||||
'compound command bypass: find -exec rm');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('denies find -exec rm -rf {} \\; preceded by ; (bypass via semicolon)', () => {
|
||||
expectDestructiveDeny('true; find . -name "*.log" -exec rm -rf {} \\;',
|
||||
'semicolon bypass: find -exec rm -rf');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('denies find -exec rm {} \\; in pipeline (bypass via pipe)', () => {
|
||||
expectDestructiveDeny('echo start | find . -exec rm {} \\;',
|
||||
'pipe bypass: find -exec rm');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('denies find -exec rm {} \\; after || (OR-chain bypass)', () => {
|
||||
expectDestructiveDeny('false || find . -exec rm {} \\;',
|
||||
'OR-chain bypass: find -exec rm');
|
||||
})) passed++; else failed++;
|
||||
|
||||
if (test('allows find -exec echo {} \\; (non-destructive, routine gate)', () => {
|
||||
clearState();
|
||||
const input = { tool_name: 'Bash', tool_input: { command: 'find . -name "*.tmp" -exec echo {} \\;' } };
|
||||
|
||||
Reference in New Issue
Block a user