Skip to content

Commit 12ad524

Browse files
committed
fix(hooks): align pre-push .env detection + fix sed redaction regex (Bugbot)
Two issues from Cursor Bugbot's review of cli #1279: 1. token-guard sed redaction regex couldn't cross delimiter boundary (high). The pattern /\bsed\b[^|]*s[/|#][^/|#]*=[^/|#]*<?redact/i used [^/|#]* which stops at the / between sed pattern and replacement, so 'sed s/=.*/=<redacted>/' (the canonical fix the error message suggests) never matched. Replaced with [\s\S]*? to reach across the delimiter. 2. pre-push.mts .env detection only matched root-level .env / .env.local (high). commit-msg.mts and pre-commit.mts both use basename() with a broader pattern. pre-push is the mandatory enforcement layer for --no-verify bypasses; weaker detection there meant a nested packages/cli/.env.local would slip through. Aligned to basename- based matching with the same allowlist (.env.example/.env.test/ .env.precommit).
1 parent f2e7e7e commit 12ad524

2 files changed

Lines changed: 20 additions & 4 deletions

File tree

.claude/hooks/token-guard/index.mts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,15 @@ const SENSITIVE_ENV_NAMES = [
4141
]
4242

4343
// Pipelines that "launder" earlier-stage secrets into safe output.
44+
// The first two patterns match `sed 's/.../redact.../'` and
45+
// `sed 's/.../FOO=*****/'` regardless of which delimiter sed uses
46+
// (`/`, `#`, `|`). `[\s\S]*?` reaches across the delimiter between
47+
// the search and replacement parts (the previous `[^/|#]*` couldn't
48+
// cross `/` and so missed the canonical `sed 's/=.*/=<redacted>/'`
49+
// — the very command the token-guard error message suggests).
4450
const REDACTION_MARKERS = [
45-
/\bsed\b[^|]*s[/|#][^/|#]*=[^/|#]*<?redact/i,
46-
/\bsed\b[^|]*s[/|#][^/|#]*[A-Z_]+=[^/|#]*\*+/i,
51+
/\bsed\b[^|]*s[/|#][\s\S]*?<?redact/i,
52+
/\bsed\b[^|]*s[/|#][\s\S]*?[A-Z_]+=[\s\S]*?\*{3,}/i,
4753
/\|\s*cut\b[^|]*-d['"]?=['"]?\s*-f\s*1/i,
4854
/\|\s*awk\b[^|]*-F\s*['"]?=['"]?/i,
4955
/>\s*\/dev\/null/,

.git-hooks/pre-push.mts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import { spawnSync } from 'node:child_process'
1919
import { existsSync, statSync } from 'node:fs'
2020

21+
import { basename } from 'node:path'
2122
import process from 'node:process'
2223

2324
import {
@@ -190,8 +191,17 @@ const scanFilesInRange = (range: string): number => {
190191
return 0
191192
}
192193

193-
// Top-level sensitive filenames in the change set.
194-
const envHits = changed.filter(f => /^\.env(\.local)?$/.test(f))
194+
// .env files at any depth — match commit-msg.mts and pre-commit.mts.
195+
// Allow .env.example, .env.test, .env.precommit (templates / tracked
196+
// placeholders); block bare .env / .env.local / .env.production /
197+
// anything else regardless of directory depth.
198+
const envHits = changed.filter(f => {
199+
const base = basename(f)
200+
return (
201+
/^\.env(\.[^/]+)?$/.test(base) &&
202+
!/^\.env\.(example|test|precommit)$/.test(base)
203+
)
204+
})
195205
if (envHits.length > 0) {
196206
out(red('✗ BLOCKED: Attempting to push .env file!'))
197207
out(`Files: ${envHits.join(', ')}`)

0 commit comments

Comments
 (0)