Skip to content

fix(hooks): prevent false positives on quoted strings in block-env-fi… - #618

Open
AVPthegreat wants to merge 1 commit into
FailproofAI:mainfrom
AVPthegreat:fix/block-env-files-quoted-false-positives
Open

fix(hooks): prevent false positives on quoted strings in block-env-fi…#618
AVPthegreat wants to merge 1 commit into
FailproofAI:mainfrom
AVPthegreat:fix/block-env-files-quoted-false-positives

Conversation

@AVPthegreat

Copy link
Copy Markdown

Summary

Fixes #49 by stripping quoted string literals ("..." and '...') before checking command regexes in block-env-files and protect-env-vars, eliminating false positives on commit messages, comments, and instructions containing .env or env.


❌ Root Cause Analysis

In src/hooks/builtin-policies.ts, block-env-files and protect-env-vars used raw string regexes (ENV_CMD_RE and ENV_PRINTENV_RE) against the full command string:

const ENV_CMD_RE = /\.env(?:\b|\s|$|\.)/;
const ENV_PRINTENV_RE = /(?:^|\s|;|&&|\|\|)(?:env|printenv)(?:\s|$|;|&&|\|)/;

Why it failed:

  1. When a user or agent ran legitimate git or echo commands containing quoted string messages (e.g., git commit -m "update .env.example documentation" or git commit -m "add env variable configuration"):
    • The regex matched .env or env inside the string literal argument "update .env.example...".
    • The policy triggered a false positive and blocked a completely safe git commit or echo command.

✅ Fix Details

Added stripQuotedStrings helper to strip double-quoted ("...") and single-quoted ('...') string argument values before evaluating block-env-files and protect-env-vars command regexes:

/** Strip quoted string literals ("..." and '...') from a bash command line to avoid false positives on comments/messages. */
function stripQuotedStrings(cmd: string): string {
  return cmd.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g, '""');
}

Updated blockEnvFiles and protectEnvVars in src/hooks/builtin-policies.ts:

if (ctx.toolName === "Bash") {
  const unquotedCmd = stripQuotedStrings(cmd);
  if (ENV_CMD_RE.test(unquotedCmd)) {
    return deny("Command references .env file");
  }
}

🧪 Unit Tests & Verification

Added test case to __tests__/hooks/builtin-policies.test.ts:

it("allows git commit with .env mentioned in quoted message", async () => {
  const ctx = makeCtx({ toolName: "Bash", toolInput: { command: 'git commit -m "update .env.example documentation"' } });
  expect((await policy.fn(ctx)).decision).toBe("allow");
});

Test Results:

  • Ran vitest run __tests__/hooks/builtin-policies.test.ts
  • Result: ✓ 470 passed (470)

Copilot AI review requested due to automatic review settings July 28, 2026 09:33
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@AVPthegreat, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bd2dc551-cf44-42eb-a7ab-1fb3675e9685

📥 Commits

Reviewing files that changed from the base of the PR and between af74838 and c67843b.

📒 Files selected for processing (2)
  • __tests__/hooks/builtin-policies.test.ts
  • src/hooks/builtin-policies.ts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hermes-exosphere

Copy link
Copy Markdown
Contributor

Your PR is awaiting review by a reviewer. Till then you can join the Discord for conversation: https://discord.befailproof.ai

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the environment-related builtin policies to reduce false-positive blocks caused by .env / env mentions inside quoted string literals (e.g., git commit messages or PR bodies), and adds a unit test covering one of those cases.

Changes:

  • Added a stripQuotedStrings() helper to remove "..." / '...' string literals before applying selected command regex checks.
  • Updated protect-env-vars and block-env-files to run their regex detection against a “quote-stripped” version of the command.
  • Added a unit test ensuring a git commit -m "… .env …" command is allowed.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/hooks/builtin-policies.ts Adds quote-stripping and applies it to env-related command checks to avoid false positives from quoted messages.
__tests__/hooks/builtin-policies.test.ts Adds a unit test for allowing .env mentions in quoted git commit -m messages.
Comments suppressed due to low confidence (1)

src/hooks/builtin-policies.ts:546

  • block-env-files can now be bypassed by quoting the file path (e.g. cat ".env" or cp ".env" /tmp/x). Because stripQuotedStrings() runs unconditionally, the .env reference disappears from unquotedCmd and the policy allows the command.
  if (ctx.toolName === "Bash") {
    const unquotedCmd = stripQuotedStrings(cmd);
    if (ENV_CMD_RE.test(unquotedCmd)) {
      return deny("Command references .env file");
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 498 to 502
const cmd = getCommand(ctx);
const unquotedCmd = stripQuotedStrings(cmd);
// Block: env, printenv, echo $VAR, export VAR=
if (ENV_PRINTENV_RE.test(cmd)) {
if (ENV_PRINTENV_RE.test(unquotedCmd)) {
return deny("Command reads environment variables");
Comment on lines +493 to +497

it("allows git commit with .env mentioned in quoted message", async () => {
const ctx = makeCtx({ toolName: "Bash", toolInput: { command: 'git commit -m "update .env.example documentation"' } });
expect((await policy.fn(ctx)).decision).toBe("allow");
});
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.

bug: block-env-files and protect-env-vars false-positive on quoted string content

3 participants