guardvibe 3.1.11 → 3.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/tools/check-code.js +47 -1
- package/package.json +1 -1
|
@@ -333,6 +333,13 @@ export function analyzeCode(code, language, framework, filePath, configDir, rule
|
|
|
333
333
|
while ((lit = literalUrlAssignRe.exec(code)) !== null)
|
|
334
334
|
literalUrlVars.add(lit[1]);
|
|
335
335
|
}
|
|
336
|
+
// jsforce SOQL skip signal for VG123. jsforce's `conn.query()` is SOQL
|
|
337
|
+
// (Salesforce's query language), not SQL — different injection semantics, and
|
|
338
|
+
// jsforce does not support parameterized queries. The documented practice is
|
|
339
|
+
// manual escape via a `sanitize*Soql*` helper. File-level boolean: cheaper
|
|
340
|
+
// than re-testing both regexes per match.
|
|
341
|
+
const fileIsJsforceWithSoqlSanitizer = /from\s+["']@?jsforce[\w@/-]*["']/i.test(code) &&
|
|
342
|
+
/sanitiz\w*Soql\w*/i.test(code);
|
|
336
343
|
// Config: check custom auth function names from .guardviberc
|
|
337
344
|
if (!codeHasAuthGuard && config.authFunctions && config.authFunctions.length > 0) {
|
|
338
345
|
const customPattern = new RegExp(`(?:${config.authFunctions.join("|")})\\s*\\(`, "i");
|
|
@@ -363,7 +370,7 @@ export function analyzeCode(code, language, framework, filePath, configDir, rule
|
|
|
363
370
|
// agent.get('/?q=' + sqlPayload) which match the regex but aren't database calls
|
|
364
371
|
// - VG042/VG678: HTTP-response/security-header rules (tests don't serve to real users)
|
|
365
372
|
const isTestFile = filePath && /(?:\.(?:[\w-]+-)?(?:spec|test|e2e|stories|cy)\.(?:ts|tsx|js|jsx|mjs|cjs)$|\/__tests__\/|\/tests?\/|\/cypress\/|\/playwright\/)/i.test(filePath);
|
|
366
|
-
if (isTestFile && ["VG001", "VG062", "VG010", "VG011", "VG013", "VG014", "VG042", "VG130", "VG678", "VG955", "VG133", "VG1021", "VG409"].includes(rule.id))
|
|
373
|
+
if (isTestFile && ["VG001", "VG062", "VG010", "VG011", "VG012", "VG013", "VG014", "VG042", "VG130", "VG678", "VG955", "VG133", "VG1021", "VG409"].includes(rule.id))
|
|
367
374
|
continue;
|
|
368
375
|
// VG955 (Missing Pagination on List Endpoint): only fire on actual request-handling
|
|
369
376
|
// surfaces — API routes, App Router `route.{ts,tsx}`, pages/api, or Server Actions.
|
|
@@ -877,6 +884,45 @@ export function analyzeCode(code, language, framework, filePath, configDir, rule
|
|
|
877
884
|
if (isServiceVerbCall && !hasSqlKeyword)
|
|
878
885
|
continue;
|
|
879
886
|
}
|
|
887
|
+
// Skip XSS-family rules (VG012/VG408/VG042/VG852) when a lint-suppression
|
|
888
|
+
// comment for the corresponding rule sits within a small window around the
|
|
889
|
+
// matched line. Universal: biome `lint/security/noDangerouslySetInnerHtml`
|
|
890
|
+
// ignore (most JSX cases) or eslint `react/no-danger` disable. Window is
|
|
891
|
+
// ±3 lines because (a) the rule may fire on the comment line itself when
|
|
892
|
+
// its pattern matches the `dangerouslySetInnerHtml` substring inside the
|
|
893
|
+
// biome ignore directive, and (b) JSX attribute rules often fire 2-3 lines
|
|
894
|
+
// below a `{/* biome-ignore ... */}` placed above the opening tag. The
|
|
895
|
+
// suppression comment is the developer's explicit acceptance of the
|
|
896
|
+
// exception (almost always accompanied by a sanitization rationale).
|
|
897
|
+
if (["VG012", "VG408", "VG042", "VG852"].includes(rule.id)) {
|
|
898
|
+
const window = lines
|
|
899
|
+
.slice(Math.max(0, lineNumber - 4), Math.min(lines.length, lineNumber + 3))
|
|
900
|
+
.join("\n");
|
|
901
|
+
if (/biome-ignore\s+lint\/security\/noDangerouslySetInnerHtml\b/i.test(window))
|
|
902
|
+
continue;
|
|
903
|
+
if (/eslint-disable(?:-next-line)?\b[^\n]{0,200}react\/no-danger\b/i.test(window))
|
|
904
|
+
continue;
|
|
905
|
+
}
|
|
906
|
+
// Skip VG012 when the right-hand side is a hardcoded string literal with
|
|
907
|
+
// no interpolation. No user input can flow in; the markup is fully
|
|
908
|
+
// developer-controlled.
|
|
909
|
+
if (rule.id === "VG012") {
|
|
910
|
+
const matchedLine = lines[lineNumber - 1] ?? "";
|
|
911
|
+
if (/\.\w+\s*=\s*"[^"\n]*"\s*;?\s*$/.test(matchedLine) && /\.innerHTML\s*=/.test(matchedLine))
|
|
912
|
+
continue;
|
|
913
|
+
if (/\.\w+\s*=\s*'[^'\n]*'\s*;?\s*$/.test(matchedLine) && /\.innerHTML\s*=/.test(matchedLine))
|
|
914
|
+
continue;
|
|
915
|
+
}
|
|
916
|
+
// Skip VG010/VG123 (SQL injection family) on jsforce SOQL calls. SOQL has
|
|
917
|
+
// different injection semantics than SQL and jsforce does not support
|
|
918
|
+
// parameterized queries — the documented practice is manual escape via a
|
|
919
|
+
// `sanitize*Soql*` helper. File must import jsforce AND use a SOQL
|
|
920
|
+
// sanitizer — both required, so a jsforce file that forgets to escape
|
|
921
|
+
// still fires. Both VG010 and VG123 are listed because the dedup logic
|
|
922
|
+
// (isDuplicatePair) collapses them on the same line; without skipping
|
|
923
|
+
// both, VG010 just takes over when VG123 is suppressed.
|
|
924
|
+
if ((rule.id === "VG123" || rule.id === "VG010") && fileIsJsforceWithSoqlSanitizer)
|
|
925
|
+
continue;
|
|
880
926
|
// Skip supply chain rules for known legitimate packages
|
|
881
927
|
if (["VG872", "VG873"].includes(rule.id)) {
|
|
882
928
|
const pkgMatch = /"([\w@/-]+)"/.exec(match[0]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "guardvibe",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.13",
|
|
4
4
|
"mcpName": "io.github.goklab/guardvibe",
|
|
5
5
|
"description": "Security MCP for vibe coding. 390 rules, 36 tools, CLI + doctor. Host security, auth coverage mapping, LLM-powered deep scan (IDOR/business logic), taint analysis, +25 AI-native rules (MCP supply-chain, RAG/vector poisoning, agent loop DoS, public-prefix LLM keys, sandbox bypass). Plus Next.js, Supabase, Clerk, Stripe, Prisma, tRPC, Hono, GraphQL, Convex, Turso, Uploadthing, AI SDK, and the full AI-generated stack.",
|
|
6
6
|
"type": "module",
|