Skip to content

Commit 39b27c0

Browse files
committed
fix(gatekeeper): fix regexp lint errors in pre-tool-use rules
Resolve eslint regexp plugin errors: - Replace .* patterns with \S+ to eliminate super-linear backtracking (regexp/no-super-linear-backtracking on \s+ combined with .*) - Remove duplicate A-Z range from case-insensitive character class (regexp/no-dupe-characters-character-class on [a-zA-Z] with /i flag) - Convert capturing groups to non-capturing in localhost URL pattern (regexp/no-unused-capturing-group)
1 parent c1f7f89 commit 39b27c0

2 files changed

Lines changed: 17 additions & 17 deletions

File tree

plugins/gatekeeper/dist/pre-tool-use.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// plugins/gatekeeper/src/pre-tool-use.ts
1+
// src/pre-tool-use.ts
22
import process from "node:process";
33

4-
// plugins/gatekeeper/src/chain-parser.ts
4+
// src/chain-parser.ts
55
function isDigit(ch) {
66
return ch !== undefined && ch >= "0" && ch <= "9";
77
}
@@ -124,7 +124,7 @@ function parseChainedCommand(cmd) {
124124
return { kind: "chain", parts: trimmed };
125125
}
126126

127-
// plugins/gatekeeper/src/pre-tool-use.ts
127+
// src/pre-tool-use.ts
128128
var HARD_DENY_RULES = [
129129
{ pattern: /^rm\s+-rf\s+\/(?:\s|$)/i, reason: "Filesystem root deletion blocked" },
130130
{ pattern: /^rm\s+-rf\s+\/\*(?:\s|$)/i, reason: "Destructive wildcard deletion from root blocked" },
@@ -153,24 +153,24 @@ var HARD_DENY_RULES = [
153153
];
154154
var SOFT_DENY_RULES = [
155155
{ pattern: /^git\s+push\s+--force(?:-with-lease)?\b/i, reason: "Force push needs user intent verification" },
156-
{ pattern: /^git\s+push\s+.*\s-(?!-)\S*f/i, reason: "Force push (short flag) needs user intent verification" },
157-
{ pattern: /^git\s+push\s+(?:.*\s)?(?:origin\s+)?(main|master)\s*$/i, reason: "Push to default branch needs user intent verification" },
156+
{ pattern: /^git\s+push(?:\s+\S+)*\s-(?!-)\S*f/i, reason: "Force push (short flag) needs user intent verification" },
157+
{ pattern: /^git\s+push\s+(?:\S+\s+)?(?:origin\s+)?(?:main|master)\s*$/i, reason: "Push to default branch needs user intent verification" },
158158
{ pattern: /^git\s+reset\s+--hard\b/i, reason: "Hard reset needs user intent verification" },
159159
{ pattern: /^git\s+clean\s+-[a-z]*f/i, reason: "Git clean needs user intent verification" },
160-
{ pattern: /^git\s+branch\s+-[a-zA-Z]*D/i, reason: "Force branch delete needs user intent verification" },
160+
{ pattern: /^git\s+branch\s+-[a-z]*D/i, reason: "Force branch delete needs user intent verification" },
161161
{ pattern: /^npm\s+publish\b/i, reason: "Package publish needs user intent verification" },
162162
{ pattern: /^(terraform|pulumi)\s+apply\b/i, reason: "Infrastructure apply needs user intent verification" },
163163
{ pattern: /^(terraform|pulumi)\s+destroy\b/i, reason: "Infrastructure destroy needs user intent verification" },
164164
{ pattern: /^kubectl\s+(apply|delete)\b/i, reason: "Kubernetes mutation needs user intent verification" },
165165
{ pattern: /(?:^|\s)\.claude\/settings/i, reason: "Agent self-modification needs user intent verification" },
166166
{ pattern: /\bCLAUDE\.md\b/i, reason: "Agent self-modification needs user intent verification" },
167-
{ pattern: /^git\s+commit\s+.*--no-verify\b/i, reason: "Skipping commit verification needs user intent verification" },
167+
{ pattern: /^git\s+commit(?:\s+\S+)*\s--no-verify\b/i, reason: "Skipping commit verification needs user intent verification" },
168168
{ pattern: /\bchmod\s+777\b/i, reason: "Broad permission change needs user intent verification" },
169169
{ pattern: /\b(nc|ncat|socat)\s+-l/i, reason: "Exposing local service needs user intent verification" },
170170
{ pattern: /\bpython3?\s+-m\s+http\.server/i, reason: "Exposing HTTP server needs user intent verification" },
171171
{ pattern: /\b(crontab|systemctl\s+enable|ssh-keygen|ssh-copy-id)\b/i, reason: "Unauthorized persistence needs user intent verification" },
172-
{ pattern: /\b(gcloud\s+.*add-iam|aws\s+iam|az\s+role\s+assignment)\b/i, reason: "Permission grant needs user intent verification" },
173-
{ pattern: /\bsystemctl\s+stop\s+.*log/i, reason: "Logging tampering needs user intent verification" }
172+
{ pattern: /\b(?:gcloud\s+\S+\s+add-iam|aws\s+iam|az\s+role\s+assignment)\b/i, reason: "Permission grant needs user intent verification" },
173+
{ pattern: /\bsystemctl\s+stop\s+\S*log/i, reason: "Logging tampering needs user intent verification" }
174174
];
175175
var ALLOW_RULES = [
176176
{
@@ -236,7 +236,7 @@ function classifyWebFetch(url) {
236236
return { decision: "soft_deny", reason: rule.reason };
237237
}
238238
}
239-
if (/^https?:\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0)(:\d+)?/i.test(url)) {
239+
if (/^https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0)(?::\d+)?/i.test(url)) {
240240
return { decision: "allow", reason: "Safe localhost request" };
241241
}
242242
return null;

plugins/gatekeeper/src/pre-tool-use.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ export const HARD_DENY_RULES: Rule[] = [
5353
export const SOFT_DENY_RULES: Rule[] = [
5454
// Git destructive operations
5555
{ pattern: /^git\s+push\s+--force(?:-with-lease)?\b/i, reason: 'Force push needs user intent verification' },
56-
{ pattern: /^git\s+push\s+.*\s-(?!-)\S*f/i, reason: 'Force push (short flag) needs user intent verification' },
57-
{ pattern: /^git\s+push\s+(?:.*\s)?(?:origin\s+)?(main|master)\s*$/i, reason: 'Push to default branch needs user intent verification' },
56+
{ pattern: /^git\s+push(?:\s+\S+)*\s-(?!-)\S*f/i, reason: 'Force push (short flag) needs user intent verification' },
57+
{ pattern: /^git\s+push\s+(?:\S+\s+)?(?:origin\s+)?(?:main|master)\s*$/i, reason: 'Push to default branch needs user intent verification' },
5858
{ pattern: /^git\s+reset\s+--hard\b/i, reason: 'Hard reset needs user intent verification' },
5959
{ pattern: /^git\s+clean\s+-[a-z]*f/i, reason: 'Git clean needs user intent verification' },
60-
{ pattern: /^git\s+branch\s+-[a-zA-Z]*D/i, reason: 'Force branch delete needs user intent verification' },
60+
{ pattern: /^git\s+branch\s+-[a-z]*D/i, reason: 'Force branch delete needs user intent verification' },
6161

6262
// Deploy/publish
6363
{ pattern: /^npm\s+publish\b/i, reason: 'Package publish needs user intent verification' },
@@ -70,7 +70,7 @@ export const SOFT_DENY_RULES: Rule[] = [
7070
{ pattern: /\bCLAUDE\.md\b/i, reason: 'Agent self-modification needs user intent verification' },
7171

7272
// Security weakening — only match --no-verify on commit (not push, which just skips pre-push hook)
73-
{ pattern: /^git\s+commit\s+.*--no-verify\b/i, reason: 'Skipping commit verification needs user intent verification' },
73+
{ pattern: /^git\s+commit(?:\s+\S+)*\s--no-verify\b/i, reason: 'Skipping commit verification needs user intent verification' },
7474
{ pattern: /\bchmod\s+777\b/i, reason: 'Broad permission change needs user intent verification' },
7575

7676
// Expose local services
@@ -81,10 +81,10 @@ export const SOFT_DENY_RULES: Rule[] = [
8181
{ pattern: /\b(crontab|systemctl\s+enable|ssh-keygen|ssh-copy-id)\b/i, reason: 'Unauthorized persistence needs user intent verification' },
8282

8383
// Permission grants (IAM/RBAC)
84-
{ pattern: /\b(gcloud\s+.*add-iam|aws\s+iam|az\s+role\s+assignment)\b/i, reason: 'Permission grant needs user intent verification' },
84+
{ pattern: /\b(?:gcloud\s+\S+\s+add-iam|aws\s+iam|az\s+role\s+assignment)\b/i, reason: 'Permission grant needs user intent verification' },
8585

8686
// Logging/audit tampering
87-
{ pattern: /\bsystemctl\s+stop\s+.*log/i, reason: 'Logging tampering needs user intent verification' },
87+
{ pattern: /\bsystemctl\s+stop\s+\S*log/i, reason: 'Logging tampering needs user intent verification' },
8888
]
8989

9090
// ─── Bash: Allow rules (safe commands, instant approve) ─────────────────────
@@ -180,7 +180,7 @@ export function classifyWebFetch(url: string): { decision: Decision, reason: str
180180
}
181181

182182
// Localhost and known dev services are safe
183-
if (/^https?:\/\/(localhost|127\.0\.0\.1|0\.0\.0\.0)(:\d+)?/i.test(url)) {
183+
if (/^https?:\/\/(?:localhost|127\.0\.0\.1|0\.0\.0\.0)(?::\d+)?/i.test(url)) {
184184
return { decision: 'allow', reason: 'Safe localhost request' }
185185
}
186186

0 commit comments

Comments
 (0)