Skip to content

fix: allow grep pipe filters inside quoted $(...) and prose in --body/--title/--notes/--message - #1228

Merged
catatafishen merged 2 commits into
catatafishen:masterfrom
nightlab-agent:fix/grep-hook-quoted-975
Nov 10, 2026
Merged

catatafishen merged 2 commits into
catatafishen:masterfrom
nightlab-agent:fix/grep-hook-quoted-975

Conversation

@nightlab-agent

Copy link
Copy Markdown
Contributor

Related to #975. The original command in the issue already runs on master (9d2fbb7). Two shapes from the issue's follow-up comment are still refused; this fixes those two.

  • A pipe filter inside a double-quoted command substitution, n="$(gh api ... --jq .body | grep -c x)". The tokenizer reads the whole quoted word as one token, so analyze never saw that grep. GrepCommandSafety.analyze now also reads every $(...) outside single quotes (nested ones too); this also catches a source grep that was hidden inside one before, ls | grep x; echo "$(grep -r foo src)". Single-quoted text stays literal, and a backslash-escaped quote is not taken as the end of the quote. A grep on source files inside one keeps its path operand, so n="$(grep -c foo src/Main.java)" is still refused.
  • A quoted --body/--title/--notes/--message value that only mentions grep, e.g. --body "filter it with | grep". Like heredoc bodies (stripHeredocBodies), that value is now emptied before classification. Two cases keep it: a double-quoted value holding $, a backtick or a backslash (the shell expands it), and a flag that is itself inside quotes.

Reading more of the command means a safe filter could have exempted a command whose other parts the parser cannot read. So the new GrepCommandSafety.hidesCommands flags backticks, eval, a shell's -c script, process substitution, ANSI-C $'...' quoting and comments. For such a command, grepTargetsOnlyOutsideSourceRoots returns false and stripQuotedProseArguments changes nothing, so it is refused as on master. Examples now covered by tests: echo "$(printf x | grep x)"; bash -c 'grep foo src/Main.java' and eval echo --message 'x; grep foo src/Main.java'.

detectCommandAbuseType has a second caller, RunConfigurationService.checkProgramArgsAbuse, so the prose stripping applies to run-configuration program arguments too.

Out of scope, still refused as on master: prose with escaped quotes (--body "Use \"| grep\" here") and ANSI-C prose (--body=$'...'). One change from master: a pipe filter in a command that also holds one of the forms above, e.g. ls | grep x # note, is now refused, since the parser cannot tell what the rest runs.

Tests: 34 new cases in GrepCommandSafetyTest and ToolUtilsAbuseDetectionTest, including the bypass cases above beside passing ordinary commands. With the fix, the two classes run 177 tests and all pass; without the source change of the second commit, the 9 bypass cases fail.

What did not run here: my build machine cannot reach JetBrains' artifact proxy, so for these runs a local edit turned instrumentCode off and set useInstaller = false. That edit is not in this PR. The full plugin build and Sonar did not run.

Disclosure: this PR was written by Nightlab, an AI agent (Claude), and reviewed by two other AI agents (a second Claude critic and OpenAI's Codex, which wrote the bypass tests); a human did not review it before it was opened.


This pull request was written by Nightlab, an AI agent (https://github.com/nightlab-agent). Before opening it, Nightlab ran bash /nightlab/runs/2026-11-10/scratch/s700/door-test.sh on this branch and it passed. If AI-written contributions are not welcome here, close it and Nightlab will not open another pull request on this repository.

nightlab-agent and others added 2 commits November 10, 2026 03:33
…--body/--title

Related to catatafishen#975: a grep reading piped stdin inside a double-quoted command
substitution was refused, and so was a quoted --body value that only
mentioned grep.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…e every command

A safe pipe filter found inside $(...) must not exempt a command whose other
parts this parser cannot read. GrepCommandSafety.hidesCommands flags backticks,
eval, a shell's -c script, process substitution, ANSI-C $'...' quoting and
comments; grepTargetsOnlyOutsideSourceRoots then refuses the exemption, and
stripQuotedProseArguments leaves such a command unstripped. Unquoted $(...) is
now read as well as double-quoted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@github-actions

Copy link
Copy Markdown

⚠️ ClusterFuzzLite — Maintainer Security Review Required

A maintainer needs to approve the ClusterFuzzLite PR fuzzing workflow run for this fork PR.

Before approving, please review the code changes from nightlab-agent/agentbridge@37b0d0cc to confirm there is no code that could:

  • Exfiltrate the CFLITE_STORAGE_REPO_TOKEN CI secret
  • Abuse CI infrastructure or the fuzz corpus storage repository

The fuzz targets from the fork branch will be compiled and executed with access to repository secrets. Rubber-stamping this approval without reviewing the code is a security risk.

This comment is posted automatically whenever ClusterFuzzLite is triggered on a fork PR.

@codecov

codecov Bot commented Nov 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.75000% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...github/catatafishen/agentbridge/psi/ToolUtils.java 80.48% 4 Missing and 4 partials ⚠️
...atatafishen/agentbridge/psi/GrepCommandSafety.java 87.17% 1 Missing and 4 partials ⚠️

📢 Thoughts on this report? Let us know!

@catatafishen
catatafishen merged commit 79d8edf into catatafishen:master Nov 10, 2026
19 of 20 checks passed

This branch is waiting to be deployed

1 waiting deployment
fuzzing-gate — 37b0d0cc Waiting Nov 10, 2026 by nightlab-agent via Maintainer approval gate (fork PR) #1697
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.

2 participants