guardvibe 1.9.5 → 1.9.6
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/cli.js +3 -3
- package/build/tools/check-code.js +55 -5
- package/package.json +1 -1
package/build/cli.js
CHANGED
|
@@ -50,6 +50,9 @@ function setupPlatform(name) {
|
|
|
50
50
|
}
|
|
51
51
|
if (existing.mcpServers["guardvibe"]) {
|
|
52
52
|
console.log(` [OK] GuardVibe already configured in ${platform.description}`);
|
|
53
|
+
// Still ensure CLAUDE.md and .gitignore are set up
|
|
54
|
+
if (name === "claude")
|
|
55
|
+
setupClaudeHooksAndGuide();
|
|
53
56
|
return true;
|
|
54
57
|
}
|
|
55
58
|
existing.mcpServers["guardvibe"] = GUARDVIBE_MCP_CONFIG;
|
|
@@ -225,9 +228,6 @@ jobs:
|
|
|
225
228
|
with:
|
|
226
229
|
node-version: "22"
|
|
227
230
|
|
|
228
|
-
- name: Install dependencies
|
|
229
|
-
run: npm ci
|
|
230
|
-
|
|
231
231
|
- name: Run GuardVibe security scan
|
|
232
232
|
run: npx -y guardvibe-scan --format sarif --output guardvibe-results.sarif
|
|
233
233
|
|
|
@@ -344,6 +344,7 @@ export function formatFindingsJson(findings, extra) {
|
|
|
344
344
|
return JSON.stringify({
|
|
345
345
|
summary: {
|
|
346
346
|
total: findings.length, critical, high, medium, low,
|
|
347
|
+
// blocked: true when critical or high findings exist (would fail --fail-on high)
|
|
347
348
|
blocked: critical > 0 || high > 0,
|
|
348
349
|
...extra,
|
|
349
350
|
},
|
|
@@ -366,19 +367,68 @@ export function checkCode(code, language, framework, filePath, configDir, format
|
|
|
366
367
|
}
|
|
367
368
|
function formatCleanReport(language, framework) {
|
|
368
369
|
const ctx = framework ? ` (${framework})` : "";
|
|
370
|
+
const tips = getLanguageTips(language, framework);
|
|
369
371
|
return [
|
|
370
372
|
`# GuardVibe Security Report`,
|
|
371
373
|
``,
|
|
372
374
|
`**Language:** ${language}${ctx}`,
|
|
373
375
|
`**Status:** No security issues detected`,
|
|
374
376
|
``,
|
|
375
|
-
`
|
|
376
|
-
|
|
377
|
-
`- Validate all user input with schemas (zod, joi)`,
|
|
378
|
-
`- Use environment variables for secrets`,
|
|
379
|
-
`- Add rate limiting to API endpoints`,
|
|
377
|
+
`Tips for ${language}${ctx}:`,
|
|
378
|
+
...tips.map(t => `- ${t}`),
|
|
380
379
|
].join("\n");
|
|
381
380
|
}
|
|
381
|
+
function getLanguageTips(language, framework) {
|
|
382
|
+
if (framework === "nextjs" || framework === "next")
|
|
383
|
+
return [
|
|
384
|
+
"Use `server-only` imports in files with secrets or DB access",
|
|
385
|
+
"Validate Server Action inputs with zod schemas",
|
|
386
|
+
"Set `serverActions.allowedOrigins` in next.config",
|
|
387
|
+
"Add security headers via `headers()` in next.config",
|
|
388
|
+
];
|
|
389
|
+
if (framework === "express" || framework === "fastify" || framework === "hono")
|
|
390
|
+
return [
|
|
391
|
+
"Add rate limiting middleware to auth and write endpoints",
|
|
392
|
+
"Use helmet() for security headers",
|
|
393
|
+
"Validate request body with zod or joi before processing",
|
|
394
|
+
"Never reflect user input in error responses",
|
|
395
|
+
];
|
|
396
|
+
if (language === "python")
|
|
397
|
+
return [
|
|
398
|
+
"Use parameterized queries — never f-strings in SQL",
|
|
399
|
+
"Add `Depends(get_current_user)` to protected routes",
|
|
400
|
+
"Pin dependency versions in requirements.txt",
|
|
401
|
+
"Use `secrets.compare_digest()` for token comparison",
|
|
402
|
+
];
|
|
403
|
+
if (language === "sql")
|
|
404
|
+
return [
|
|
405
|
+
"Use `SECURITY INVOKER` on views to respect RLS",
|
|
406
|
+
"Avoid `GRANT ALL` — use least-privilege permissions",
|
|
407
|
+
"Add `IF EXISTS` to destructive DDL for safety",
|
|
408
|
+
"Use parameterized queries in application code",
|
|
409
|
+
];
|
|
410
|
+
if (language === "dockerfile")
|
|
411
|
+
return [
|
|
412
|
+
"Use specific image tags, never `latest`",
|
|
413
|
+
"Run as non-root user with `USER` directive",
|
|
414
|
+
"Use multi-stage builds to minimize attack surface",
|
|
415
|
+
"Don't copy `.env` or secrets into the image",
|
|
416
|
+
];
|
|
417
|
+
if (language === "yaml" || language === "terraform")
|
|
418
|
+
return [
|
|
419
|
+
"Never hardcode secrets in config — use env vars or secrets manager",
|
|
420
|
+
"Pin action/provider versions to specific SHA or tag",
|
|
421
|
+
"Use least-privilege IAM policies",
|
|
422
|
+
"Enable audit logging for infrastructure changes",
|
|
423
|
+
];
|
|
424
|
+
// Default for JS/TS
|
|
425
|
+
return [
|
|
426
|
+
"Keep dependencies updated (`npm audit`)",
|
|
427
|
+
"Validate all user input with schemas (zod, joi)",
|
|
428
|
+
"Use environment variables for secrets",
|
|
429
|
+
"Use `textContent` instead of `innerHTML` for user data",
|
|
430
|
+
];
|
|
431
|
+
}
|
|
382
432
|
function formatReport(findings, language, framework) {
|
|
383
433
|
const ctx = framework ? ` (${framework})` : "";
|
|
384
434
|
// Severity ordering
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "guardvibe",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.6",
|
|
4
4
|
"description": "Security MCP for vibe coding. 277 rules, 24 tools for Next.js, Supabase, Clerk, Stripe, Prisma, tRPC, Hono, GraphQL, Convex, Turso, Uploadthing, AI SDK, and the full AI-generated stack.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|