guardvibe 0.6.3 → 0.7.0

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.
Files changed (85) hide show
  1. package/README.md +93 -156
  2. package/build/data/rules/auth.d.ts +3 -0
  3. package/build/data/rules/auth.d.ts.map +1 -0
  4. package/build/data/rules/auth.js +100 -0
  5. package/build/data/rules/auth.js.map +1 -0
  6. package/build/data/rules/core.js +11 -11
  7. package/build/data/rules/core.js.map +1 -1
  8. package/build/data/rules/database.d.ts +3 -0
  9. package/build/data/rules/database.d.ts.map +1 -0
  10. package/build/data/rules/database.js +100 -0
  11. package/build/data/rules/database.js.map +1 -0
  12. package/build/data/rules/deployment.d.ts +3 -0
  13. package/build/data/rules/deployment.d.ts.map +1 -0
  14. package/build/data/rules/deployment.js +192 -0
  15. package/build/data/rules/deployment.js.map +1 -0
  16. package/build/data/rules/index.d.ts.map +1 -1
  17. package/build/data/rules/index.js +8 -6
  18. package/build/data/rules/index.js.map +1 -1
  19. package/build/data/rules/nextjs.d.ts +3 -0
  20. package/build/data/rules/nextjs.d.ts.map +1 -0
  21. package/build/data/rules/nextjs.js +148 -0
  22. package/build/data/rules/nextjs.js.map +1 -0
  23. package/build/index.js +36 -19
  24. package/build/index.js.map +1 -1
  25. package/build/tools/check-code.d.ts +3 -2
  26. package/build/tools/check-code.d.ts.map +1 -1
  27. package/build/tools/check-code.js +25 -4
  28. package/build/tools/check-code.js.map +1 -1
  29. package/build/tools/check-package-health.d.ts +29 -0
  30. package/build/tools/check-package-health.d.ts.map +1 -0
  31. package/build/tools/check-package-health.js +142 -0
  32. package/build/tools/check-package-health.js.map +1 -0
  33. package/build/tools/check-project.d.ts +1 -1
  34. package/build/tools/check-project.d.ts.map +1 -1
  35. package/build/tools/check-project.js +24 -5
  36. package/build/tools/check-project.js.map +1 -1
  37. package/build/tools/compliance-report.d.ts +1 -1
  38. package/build/tools/compliance-report.d.ts.map +1 -1
  39. package/build/tools/compliance-report.js +33 -9
  40. package/build/tools/compliance-report.js.map +1 -1
  41. package/build/tools/export-sarif.d.ts.map +1 -1
  42. package/build/tools/export-sarif.js +7 -7
  43. package/build/tools/export-sarif.js.map +1 -1
  44. package/build/tools/scan-dependencies.d.ts +1 -1
  45. package/build/tools/scan-dependencies.d.ts.map +1 -1
  46. package/build/tools/scan-dependencies.js +25 -2
  47. package/build/tools/scan-dependencies.js.map +1 -1
  48. package/build/tools/scan-directory.d.ts +1 -1
  49. package/build/tools/scan-directory.d.ts.map +1 -1
  50. package/build/tools/scan-directory.js +33 -11
  51. package/build/tools/scan-directory.js.map +1 -1
  52. package/build/tools/scan-secrets.d.ts +1 -1
  53. package/build/tools/scan-secrets.d.ts.map +1 -1
  54. package/build/tools/scan-secrets.js +110 -57
  55. package/build/tools/scan-secrets.js.map +1 -1
  56. package/build/tools/scan-staged.d.ts +1 -1
  57. package/build/tools/scan-staged.d.ts.map +1 -1
  58. package/build/tools/scan-staged.js +29 -10
  59. package/build/tools/scan-staged.js.map +1 -1
  60. package/build/utils/config.d.ts.map +1 -1
  61. package/build/utils/config.js +19 -11
  62. package/build/utils/config.js.map +1 -1
  63. package/build/utils/manifest-parser.d.ts.map +1 -1
  64. package/build/utils/manifest-parser.js +93 -68
  65. package/build/utils/manifest-parser.js.map +1 -1
  66. package/build/utils/osv-client.d.ts.map +1 -1
  67. package/build/utils/osv-client.js +3 -2
  68. package/build/utils/osv-client.js.map +1 -1
  69. package/build/utils/typosquat.d.ts +9 -0
  70. package/build/utils/typosquat.d.ts.map +1 -0
  71. package/build/utils/typosquat.js +101 -0
  72. package/build/utils/typosquat.js.map +1 -0
  73. package/package.json +4 -5
  74. package/build/data/rules/java.d.ts +0 -3
  75. package/build/data/rules/java.d.ts.map +0 -1
  76. package/build/data/rules/java.js +0 -70
  77. package/build/data/rules/java.js.map +0 -1
  78. package/build/data/rules/php.d.ts +0 -3
  79. package/build/data/rules/php.d.ts.map +0 -1
  80. package/build/data/rules/php.js +0 -59
  81. package/build/data/rules/php.js.map +0 -1
  82. package/build/data/rules/ruby.d.ts +0 -3
  83. package/build/data/rules/ruby.d.ts.map +0 -1
  84. package/build/data/rules/ruby.js +0 -59
  85. package/build/data/rules/ruby.js.map +0 -1
@@ -0,0 +1,100 @@
1
+ // Security rules for Supabase, Prisma, and Drizzle ORM
2
+ export const databaseRules = [
3
+ {
4
+ id: "VG430",
5
+ name: "Supabase Anon Key on Server",
6
+ severity: "high",
7
+ owasp: "A01:2025 Broken Access Control",
8
+ description: "Using the anon/public key server-side bypasses Row Level Security. Use the service_role key on the server.",
9
+ pattern: /createClient\s*\([\s\S]*?(?:NEXT_PUBLIC_SUPABASE_ANON_KEY|supabaseAnonKey)/g,
10
+ languages: ["javascript", "typescript"],
11
+ fix: "Use SUPABASE_SERVICE_ROLE_KEY on the server. The anon key is for client-side use with RLS.",
12
+ fixCode: '// Server-side: use service role key\nconst supabase = createClient(\n process.env.SUPABASE_URL!,\n process.env.SUPABASE_SERVICE_ROLE_KEY!\n);',
13
+ compliance: ["SOC2:CC6.6", "HIPAA:§164.312(a)"],
14
+ },
15
+ {
16
+ id: "VG431",
17
+ name: "Supabase Missing RLS Warning",
18
+ severity: "medium",
19
+ owasp: "A01:2025 Broken Access Control",
20
+ description: "Supabase client queries data. Ensure Row Level Security policies are configured on your tables.",
21
+ pattern: /supabase\s*\.from\s*\(\s*["']\w+["']\s*\)\s*\.(?:select|insert|update|delete|upsert)\s*\(/g,
22
+ languages: ["javascript", "typescript"],
23
+ fix: "Enable Row Level Security (RLS) on all Supabase tables and create appropriate policies.",
24
+ fixCode: "-- Enable RLS on tables\nALTER TABLE posts ENABLE ROW LEVEL SECURITY;\n\nCREATE POLICY \"Users can read own posts\"\n ON posts FOR SELECT\n USING (auth.uid() = user_id);",
25
+ compliance: ["SOC2:CC6.6"],
26
+ },
27
+ {
28
+ id: "VG432",
29
+ name: "Prisma Raw Query Injection",
30
+ severity: "critical",
31
+ owasp: "A03:2025 Injection",
32
+ description: "Prisma $queryRaw or $executeRaw with template literal interpolation. Use Prisma.sql tagged template for safe parameterization.",
33
+ pattern: /\.\$(?:queryRaw|executeRaw)`[^`]*\$\{(?!Prisma\.)/g,
34
+ languages: ["javascript", "typescript"],
35
+ fix: "Use Prisma.sql tagged template for safe parameterization.",
36
+ fixCode: 'import { Prisma } from "@prisma/client";\n\nconst result = await prisma.$queryRaw(\n Prisma.sql`SELECT * FROM users WHERE id = ${userId}`\n);',
37
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.1"],
38
+ },
39
+ {
40
+ id: "VG433",
41
+ name: "Prisma queryRawUnsafe Usage",
42
+ severity: "critical",
43
+ owasp: "A03:2025 Injection",
44
+ description: "$queryRawUnsafe and $executeRawUnsafe pass raw SQL strings without parameterization. Extremely dangerous with user input.",
45
+ pattern: /\.\$(?:queryRawUnsafe|executeRawUnsafe)\s*\(/g,
46
+ languages: ["javascript", "typescript"],
47
+ fix: "Replace with $queryRaw using Prisma.sql tagged template.",
48
+ fixCode: "const result = await prisma.$queryRaw(\n Prisma.sql`SELECT * FROM users WHERE id = ${userId}`\n);",
49
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.1"],
50
+ },
51
+ {
52
+ id: "VG434",
53
+ name: "Drizzle Unsafe SQL Interpolation",
54
+ severity: "critical",
55
+ owasp: "A03:2025 Injection",
56
+ description: "Drizzle sql tagged template with direct variable interpolation. Use sql.placeholder() for safe parameterization.",
57
+ pattern: /(?:db\.execute|db\.run|db\.get|db\.all)\s*\(\s*sql`[^`]*\$\{/g,
58
+ languages: ["javascript", "typescript"],
59
+ fix: "Use sql.placeholder() for dynamic values in Drizzle queries.",
60
+ fixCode: 'import { sql } from "drizzle-orm";\n\nconst result = await db.execute(\n sql`SELECT * FROM users WHERE id = ${sql.placeholder("id")}`,\n { id: userId }\n);',
61
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.1"],
62
+ },
63
+ {
64
+ id: "VG435",
65
+ name: "Database URL Client Exposure",
66
+ severity: "critical",
67
+ owasp: "A07:2025 Sensitive Data Exposure",
68
+ description: "DATABASE_URL or DIRECT_URL is accessed in client-side code. This exposes your database connection string to the browser.",
69
+ pattern: /["']use client["'][\s\S]*?process\.env\.(?:DATABASE_URL|DIRECT_URL)/g,
70
+ languages: ["javascript", "typescript"],
71
+ fix: "Never access database URLs in client components. Use Server Components or API routes.",
72
+ fixCode: "// Access database only server-side (no 'use client')\nexport default async function Page() {\n const data = await prisma.user.findMany();\n return <UserList users={data} />;\n}",
73
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req2.3", "HIPAA:§164.312(a)"],
74
+ },
75
+ {
76
+ id: "VG436",
77
+ name: "NEXT_PUBLIC Database URL",
78
+ severity: "critical",
79
+ owasp: "A07:2025 Sensitive Data Exposure",
80
+ description: "Database URL is prefixed with NEXT_PUBLIC_, exposing it in the client bundle.",
81
+ pattern: /NEXT_PUBLIC_\w*(?:DATABASE|DB|POSTGRES|MYSQL|MONGO|REDIS|SUPABASE_DB)\w*URL\s*=/gi,
82
+ languages: ["javascript", "typescript", "shell"],
83
+ fix: "Remove NEXT_PUBLIC_ prefix. Database URLs must only be server-side.",
84
+ fixCode: "# WRONG: exposed to client\n# NEXT_PUBLIC_DATABASE_URL=postgresql://...\n\n# CORRECT: server-side only\nDATABASE_URL=postgresql://...",
85
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req2.3", "HIPAA:§164.312(a)"],
86
+ },
87
+ {
88
+ id: "VG437",
89
+ name: "Supabase Service Role Key in Client",
90
+ severity: "critical",
91
+ owasp: "A07:2025 Sensitive Data Exposure",
92
+ description: "SUPABASE_SERVICE_ROLE_KEY is accessed in client-side code. This key bypasses RLS and grants full database access.",
93
+ pattern: /["']use client["'][\s\S]*?(?:SUPABASE_SERVICE_ROLE_KEY|SERVICE_ROLE)/g,
94
+ languages: ["javascript", "typescript"],
95
+ fix: "Never use the service role key in client code.",
96
+ fixCode: '// Server-side only\n"use server";\nconst adminClient = createClient(url, process.env.SUPABASE_SERVICE_ROLE_KEY!);',
97
+ compliance: ["SOC2:CC6.1", "HIPAA:§164.312(a)"],
98
+ },
99
+ ];
100
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/data/rules/database.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SecurityRule } from "./types.js";
2
+ export declare const deploymentRules: SecurityRule[];
3
+ //# sourceMappingURL=deployment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment.d.ts","sourceRoot":"","sources":["../../../src/data/rules/deployment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,eAAO,MAAM,eAAe,EAAE,YAAY,EA+NzC,CAAC"}
@@ -0,0 +1,192 @@
1
+ // Security rules for deployment config files
2
+ export const deploymentRules = [
3
+ // vercel.json / vercel.ts
4
+ {
5
+ id: "VG500",
6
+ name: "Vercel CORS Wildcard",
7
+ severity: "high",
8
+ owasp: "A01:2025 Broken Access Control",
9
+ description: "Vercel config sets Access-Control-Allow-Origin to wildcard (*), allowing any website to make requests.",
10
+ pattern: /["']Access-Control-Allow-Origin["'][\s\S]*?["']\*["']/g,
11
+ languages: ["vercel-config", "json"],
12
+ fix: "Restrict CORS to specific trusted origins.",
13
+ fixCode: '// vercel.json\n{\n "headers": [{\n "source": "/api/(.*)",\n "headers": [{ "key": "Access-Control-Allow-Origin", "value": "https://yourdomain.com" }]\n }]\n}',
14
+ compliance: ["SOC2:CC6.6"],
15
+ },
16
+ {
17
+ id: "VG501",
18
+ name: "Vercel Internal Rewrite Exposure",
19
+ severity: "high",
20
+ owasp: "A01:2025 Broken Access Control",
21
+ description: "Vercel rewrites expose internal service URLs to the public internet.",
22
+ pattern: /["']rewrites["']\s*:\s*\[[\s\S]*?["']destination["']\s*:\s*["']https?:\/\/(?:localhost|127\.0\.0\.1|10\.|172\.(?:1[6-9]|2\d|3[01])\.|192\.168\.)/g,
23
+ languages: ["vercel-config", "json"],
24
+ fix: "Do not rewrite to internal network addresses. Use Vercel environment variables for service URLs.",
25
+ compliance: ["SOC2:CC6.6"],
26
+ },
27
+ {
28
+ id: "VG503",
29
+ name: "Vercel Cron Missing Secret Verification",
30
+ severity: "high",
31
+ owasp: "A01:2025 Broken Access Control",
32
+ description: "Cron jobs are configured but the endpoint may not verify CRON_SECRET. Anyone could trigger the cron endpoint manually.",
33
+ pattern: /["']crons["']\s*:\s*\[[\s\S]*?["']path["']\s*:\s*["'][^"']+["']/g,
34
+ languages: ["vercel-config", "json"],
35
+ fix: "Verify the CRON_SECRET header in your cron endpoint.",
36
+ fixCode: '// app/api/cron/route.ts\nexport async function GET(request: Request) {\n const authHeader = request.headers.get("authorization");\n if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {\n return new Response("Unauthorized", { status: 401 });\n }\n}',
37
+ compliance: ["SOC2:CC6.6"],
38
+ },
39
+ {
40
+ id: "VG504",
41
+ name: "Excessive Function Duration",
42
+ severity: "medium",
43
+ owasp: "A05:2025 Security Misconfiguration",
44
+ description: "Function maxDuration is set very high. Long-running functions increase costs and attack surface.",
45
+ pattern: /["']maxDuration["']\s*:\s*(?:[3-9]\d{2}|[1-9]\d{3,})/g,
46
+ languages: ["vercel-config", "json"],
47
+ fix: "Set maxDuration to the minimum required. Default 300s is sufficient for most use cases.",
48
+ },
49
+ {
50
+ id: "VG506",
51
+ name: "Hardcoded Secret in Vercel Config",
52
+ severity: "critical",
53
+ owasp: "A07:2025 Sensitive Data Exposure",
54
+ description: "Secret or API key hardcoded in vercel.json. This file is committed to git.",
55
+ pattern: /["'](?:SECRET|KEY|TOKEN|PASSWORD|CREDENTIAL)\w*["']\s*:\s*["'][A-Za-z0-9_\-]{12,}["']/gi,
56
+ languages: ["vercel-config", "json"],
57
+ fix: "Use Vercel environment variables (vercel env add) instead of hardcoding in config files.",
58
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req2.3"],
59
+ },
60
+ // next.config
61
+ {
62
+ id: "VG507",
63
+ name: "Wildcard Remote Image Pattern",
64
+ severity: "high",
65
+ owasp: "A05:2025 Security Misconfiguration",
66
+ description: "next.config allows images from any hostname. This enables SSRF and hotlinking attacks.",
67
+ pattern: /remotePatterns\s*:\s*\[[\s\S]*?hostname\s*:\s*["'](?:\*\*|\*)["']/g,
68
+ languages: ["nextjs-config", "javascript", "typescript"],
69
+ fix: "Restrict remotePatterns to specific trusted hostnames.",
70
+ fixCode: '// next.config.ts\nimages: {\n remotePatterns: [\n { protocol: "https", hostname: "images.example.com" },\n ]\n}',
71
+ compliance: ["SOC2:CC6.6"],
72
+ },
73
+ {
74
+ id: "VG509",
75
+ name: "Powered By Header Enabled",
76
+ severity: "low",
77
+ owasp: "A05:2025 Security Misconfiguration",
78
+ description: "X-Powered-By header reveals Next.js framework. This helps attackers target known vulnerabilities.",
79
+ pattern: /poweredByHeader\s*:\s*true/g,
80
+ languages: ["nextjs-config", "javascript", "typescript"],
81
+ fix: "Set poweredByHeader to false in next.config.ts.",
82
+ fixCode: "// next.config.ts\nconst config = {\n poweredByHeader: false,\n};",
83
+ },
84
+ {
85
+ id: "VG510",
86
+ name: "Next Config CORS Wildcard",
87
+ severity: "high",
88
+ owasp: "A01:2025 Broken Access Control",
89
+ description: "Next.js config headers() sets Access-Control-Allow-Origin to wildcard (*).",
90
+ pattern: /headers\s*\(\s*\)\s*\{[\s\S]*?Access-Control-Allow-Origin[\s\S]*?["']\*["']/g,
91
+ languages: ["nextjs-config", "javascript", "typescript"],
92
+ fix: "Restrict CORS to specific trusted origins.",
93
+ compliance: ["SOC2:CC6.6"],
94
+ },
95
+ {
96
+ id: "VG512",
97
+ name: "Source Maps in Production",
98
+ severity: "medium",
99
+ owasp: "A05:2025 Security Misconfiguration",
100
+ description: "Source maps enabled in production expose original source code to attackers.",
101
+ pattern: /devtool\s*:\s*["'](?:source-map|eval-source-map|cheap-source-map)["']/g,
102
+ languages: ["nextjs-config", "javascript", "typescript"],
103
+ fix: "Disable source maps in production.",
104
+ fixCode: "// next.config.ts\nconst config = {\n productionBrowserSourceMaps: false,\n};",
105
+ compliance: ["SOC2:CC6.1"],
106
+ },
107
+ // docker-compose.yml
108
+ {
109
+ id: "VG513",
110
+ name: "Docker Compose Public Port Binding",
111
+ severity: "medium",
112
+ owasp: "A05:2025 Security Misconfiguration",
113
+ description: "Port bound to 0.0.0.0 exposes the service to all network interfaces.",
114
+ pattern: /ports\s*:\s*\n\s*-\s*["']?0\.0\.0\.0:/gm,
115
+ languages: ["docker-compose", "yaml"],
116
+ fix: "Bind to 127.0.0.1 for local-only access.",
117
+ fixCode: '# Bind to localhost only\nports:\n - "127.0.0.1:3000:3000"',
118
+ compliance: ["SOC2:CC6.6"],
119
+ },
120
+ {
121
+ id: "VG514",
122
+ name: "Docker Compose Hardcoded Secret",
123
+ severity: "critical",
124
+ owasp: "A07:2025 Sensitive Data Exposure",
125
+ description: "Secret hardcoded in docker-compose environment section. Use Docker secrets or .env file.",
126
+ pattern: /environment\s*:\s*\n(?:\s*-\s*|\s*\w+\s*:\s*)[\s\S]*?(?:SECRET|PASSWORD|TOKEN|KEY|CREDENTIAL)\w*\s*[=:]\s*\S{8,}/gi,
127
+ languages: ["docker-compose", "yaml"],
128
+ fix: "Use Docker secrets or reference a .env file instead of hardcoding.",
129
+ fixCode: "# Use .env file\nservices:\n app:\n env_file:\n - .env",
130
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req2.3"],
131
+ },
132
+ {
133
+ id: "VG515",
134
+ name: "Docker Compose Privileged Container",
135
+ severity: "critical",
136
+ owasp: "A05:2025 Security Misconfiguration",
137
+ description: "Container runs in privileged mode with full host access. This is a severe security risk.",
138
+ pattern: /privileged\s*:\s*true/g,
139
+ languages: ["docker-compose", "yaml"],
140
+ fix: "Remove privileged: true. Use specific capabilities (cap_add) if needed.",
141
+ fixCode: "# Instead of privileged: true, use specific capabilities\nservices:\n app:\n cap_add:\n - NET_ADMIN",
142
+ compliance: ["SOC2:CC6.1"],
143
+ },
144
+ {
145
+ id: "VG516",
146
+ name: "Docker Compose Host Volume Mount",
147
+ severity: "high",
148
+ owasp: "A05:2025 Security Misconfiguration",
149
+ description: "Mounting the entire host filesystem gives the container excessive access.",
150
+ pattern: /volumes\s*:\s*\n\s*-\s*["']?(?:\/:|\/etc|\/var|\/root|\/home)\s*:/gm,
151
+ languages: ["docker-compose", "yaml"],
152
+ fix: "Mount only specific directories needed by the application.",
153
+ fixCode: "# Mount only what's needed\nvolumes:\n - ./data:/app/data",
154
+ compliance: ["SOC2:CC6.1"],
155
+ },
156
+ // fly.toml / render.yaml / netlify.toml
157
+ {
158
+ id: "VG517",
159
+ name: "Platform Config Hardcoded Secret",
160
+ severity: "critical",
161
+ owasp: "A07:2025 Sensitive Data Exposure",
162
+ description: "Secret hardcoded in deployment platform config file. These files are committed to git.",
163
+ pattern: /\[env\][\s\S]*?(?:SECRET|PASSWORD|TOKEN|KEY|CREDENTIAL)\w*\s*=\s*["']?[A-Za-z0-9_\-]{12,}/gi,
164
+ languages: ["fly-config", "render-config", "netlify-config", "toml"],
165
+ fix: "Use your platform's secret management (fly secrets set, Render env groups, Netlify env vars).",
166
+ fixCode: '# fly.toml — don\'t put secrets here\n# Instead: fly secrets set SECRET_KEY=value\n\n[env]\n LOG_LEVEL = "info"',
167
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req2.3"],
168
+ },
169
+ {
170
+ id: "VG518",
171
+ name: "Platform Internal Port Exposed",
172
+ severity: "medium",
173
+ owasp: "A05:2025 Security Misconfiguration",
174
+ description: "Internal service port (database, cache) is exposed publicly.",
175
+ pattern: /internal_port\s*=\s*(?:5432|3306|6379|27017|9200|2379)/g,
176
+ languages: ["fly-config", "toml"],
177
+ fix: "Don't expose database or cache ports publicly. Use internal networking.",
178
+ compliance: ["SOC2:CC6.6"],
179
+ },
180
+ {
181
+ id: "VG520",
182
+ name: "Missing HTTPS Redirect",
183
+ severity: "medium",
184
+ owasp: "A05:2025 Security Misconfiguration",
185
+ description: "No HTTP to HTTPS redirect configured. Traffic may be sent unencrypted.",
186
+ pattern: /force_https\s*=\s*false/g,
187
+ languages: ["fly-config", "toml"],
188
+ fix: "Enable force_https to redirect all HTTP traffic to HTTPS.",
189
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req4.1"],
190
+ },
191
+ ];
192
+ //# sourceMappingURL=deployment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment.js","sourceRoot":"","sources":["../../../src/data/rules/deployment.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/rules/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAU/C,eAAO,MAAM,UAAU,qCAStB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/rules/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAW/C,eAAO,MAAM,UAAU,qCAUtB,CAAC"}
@@ -1,19 +1,21 @@
1
1
  import { coreRules } from "./core.js";
2
2
  import { goRules } from "./go.js";
3
- import { javaRules } from "./java.js";
4
- import { phpRules } from "./php.js";
5
- import { rubyRules } from "./ruby.js";
6
3
  import { dockerfileRules } from "./dockerfile.js";
7
4
  import { cicdRules } from "./cicd.js";
8
5
  import { terraformRules } from "./terraform.js";
6
+ import { nextjsRules } from "./nextjs.js";
7
+ import { authRules } from "./auth.js";
8
+ import { databaseRules } from "./database.js";
9
+ import { deploymentRules } from "./deployment.js";
9
10
  export const owaspRules = [
10
11
  ...coreRules,
11
12
  ...goRules,
12
- ...javaRules,
13
- ...phpRules,
14
- ...rubyRules,
15
13
  ...dockerfileRules,
16
14
  ...cicdRules,
17
15
  ...terraformRules,
16
+ ...nextjsRules,
17
+ ...authRules,
18
+ ...databaseRules,
19
+ ...deploymentRules,
18
20
  ];
19
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data/rules/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,GAAG,SAAS;IACZ,GAAG,OAAO;IACV,GAAG,SAAS;IACZ,GAAG,QAAQ;IACX,GAAG,SAAS;IACZ,GAAG,eAAe;IAClB,GAAG,SAAS;IACZ,GAAG,cAAc;CAClB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data/rules/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,GAAG,SAAS;IACZ,GAAG,OAAO;IACV,GAAG,eAAe;IAClB,GAAG,SAAS;IACZ,GAAG,cAAc;IACjB,GAAG,WAAW;IACd,GAAG,SAAS;IACZ,GAAG,aAAa;IAChB,GAAG,eAAe;CACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SecurityRule } from "./types.js";
2
+ export declare const nextjsRules: SecurityRule[];
3
+ //# sourceMappingURL=nextjs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../../src/data/rules/nextjs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,eAAO,MAAM,WAAW,EAAE,YAAY,EAkLrC,CAAC"}
@@ -0,0 +1,148 @@
1
+ // Security rules for Next.js App Router patterns
2
+ export const nextjsRules = [
3
+ {
4
+ id: "VG400",
5
+ name: "Client Component Secret Exposure",
6
+ severity: "critical",
7
+ owasp: "A01:2025 Broken Access Control",
8
+ description: "Server-side environment variable accessed in a 'use client' component. These values are exposed to the browser. Only NEXT_PUBLIC_ variables are safe in client components.",
9
+ pattern: /["']use client["'][\s\S]*?process\.env\.(?!NEXT_PUBLIC_)\w+/g,
10
+ languages: ["javascript", "typescript"],
11
+ fix: "Move this logic to a Server Component or Server Action. Only process.env.NEXT_PUBLIC_* variables are available in client components.",
12
+ fixCode: '// Move to a Server Component (no \'use client\')\nexport default async function Page() {\n const secret = process.env.SECRET_KEY;\n return <ClientComponent data={safeData} />;\n}',
13
+ compliance: ["SOC2:CC6.1", "HIPAA:§164.312(a)"],
14
+ },
15
+ {
16
+ id: "VG401",
17
+ name: "Server Action Missing Input Validation",
18
+ severity: "high",
19
+ owasp: "A03:2025 Injection",
20
+ description: "Server Action processes form data without schema validation. Unvalidated input can lead to injection attacks.",
21
+ pattern: /["']use server["'][\s\S]{0,500}?formData\.get\s*\(/g,
22
+ languages: ["javascript", "typescript"],
23
+ fix: "Validate all inputs with a schema library (zod, yup, valibot) before processing.",
24
+ fixCode: '"use server";\nimport { z } from "zod";\n\nconst schema = z.object({ name: z.string().min(1), email: z.string().email() });\n\nexport async function createUser(formData: FormData) {\n const data = schema.parse(Object.fromEntries(formData));\n}',
25
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.1"],
26
+ },
27
+ {
28
+ id: "VG402",
29
+ name: "Server Action Missing Auth Check",
30
+ severity: "critical",
31
+ owasp: "A01:2025 Broken Access Control",
32
+ description: "Server Action performs data mutations without verifying user authentication. Anyone can invoke Server Actions directly via POST request.",
33
+ pattern: /["']use server["'][\s\S]{0,200}?export\s+async\s+function\s+\w+\s*\([^)]*\)\s*\{(?:(?!auth\s*\(|getServerSession|currentUser|getUser|requireAuth|clerkClient)[\s\S])*?\}/g,
34
+ languages: ["javascript", "typescript"],
35
+ fix: "Always verify authentication at the start of every Server Action.",
36
+ fixCode: '"use server";\nimport { auth } from "@clerk/nextjs/server";\n\nexport async function deleteItem(id: string) {\n const { userId } = await auth();\n if (!userId) throw new Error("Unauthorized");\n}',
37
+ compliance: ["SOC2:CC6.6", "PCI-DSS:Req6.5.10", "HIPAA:§164.312(d)"],
38
+ },
39
+ {
40
+ id: "VG403",
41
+ name: "Route Handler CORS Wildcard",
42
+ severity: "high",
43
+ owasp: "A01:2025 Broken Access Control",
44
+ description: "Route handler sets Access-Control-Allow-Origin to wildcard (*). This allows any website to make requests to your API.",
45
+ pattern: /(?:GET|POST|PUT|DELETE|PATCH|OPTIONS)\s*\([\s\S]*?["']Access-Control-Allow-Origin["']\s*[,:]\s*["']\*["']/g,
46
+ languages: ["javascript", "typescript"],
47
+ fix: "Restrict CORS to specific trusted origins instead of wildcard.",
48
+ fixCode: '// Restrict to specific origin\nconst allowedOrigin = process.env.ALLOWED_ORIGIN;\nreturn new Response(data, {\n headers: { "Access-Control-Allow-Origin": allowedOrigin }\n});',
49
+ compliance: ["SOC2:CC6.6"],
50
+ },
51
+ {
52
+ id: "VG404",
53
+ name: "Middleware Auth Bypass Risk",
54
+ severity: "high",
55
+ owasp: "A01:2025 Broken Access Control",
56
+ description: "Middleware or proxy has overly broad public path matcher that may accidentally expose protected routes.",
57
+ pattern: /(?:matcher|config)\s*[=:]\s*[\s\S]*?["']\/\(\.\*\)["']/g,
58
+ languages: ["javascript", "typescript"],
59
+ fix: "Use specific path matchers instead of catch-all patterns.",
60
+ fixCode: '// Be specific with matchers\nexport const config = {\n matcher: ["/dashboard/:path*", "/api/:path*"]\n};',
61
+ compliance: ["SOC2:CC6.6"],
62
+ },
63
+ {
64
+ id: "VG405",
65
+ name: "Missing Security Headers in Next Config",
66
+ severity: "medium",
67
+ owasp: "A05:2025 Security Misconfiguration",
68
+ description: "next.config is missing important security headers (Content-Security-Policy, Strict-Transport-Security, X-Frame-Options).",
69
+ pattern: /(?:async\s+)?headers\s*\(\s*\)\s*\{[\s\S]*?return\s*\[[\s\S]*?\][\s\S]*?\}/g,
70
+ languages: ["javascript", "typescript"],
71
+ fix: "Add security headers in next.config.ts headers() function.",
72
+ fixCode: '// next.config.ts\nasync headers() {\n return [{\n source: "/(.*)",\n headers: [\n { key: "X-Frame-Options", value: "DENY" },\n { key: "X-Content-Type-Options", value: "nosniff" },\n { key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains" },\n ]\n }];\n}',
73
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req6.5.10"],
74
+ },
75
+ {
76
+ id: "VG406",
77
+ name: "Unsanitized Dynamic Route Params",
78
+ severity: "high",
79
+ owasp: "A03:2025 Injection",
80
+ description: "Dynamic route parameters (params, searchParams) are used directly in database queries or operations without validation.",
81
+ pattern: /(?:params|searchParams)\s*[\.\[]\s*["']?\w+["']?\s*[\]\)]?\s*(?:;|\))\s*[\s\S]*?(?:query|execute|findUnique|findFirst|findMany|delete|update|create)\s*\(/g,
82
+ languages: ["javascript", "typescript"],
83
+ fix: "Always validate and sanitize dynamic route parameters before using them in queries.",
84
+ fixCode: '// Validate params before use\nimport { z } from "zod";\nconst idSchema = z.string().uuid();\n\nexport default async function Page({ params }: { params: { id: string } }) {\n const id = idSchema.parse((await params).id);\n const item = await db.item.findUnique({ where: { id } });\n}',
85
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.1"],
86
+ },
87
+ {
88
+ id: "VG407",
89
+ name: "Server Data Leaked to Client Component",
90
+ severity: "high",
91
+ owasp: "A01:2025 Broken Access Control",
92
+ description: "Sensitive data (tokens, secrets, internal IDs) appears to be passed from server to client component as props.",
93
+ pattern: /(?:secret|token|password|apiKey|privateKey|internalId|ssn|creditCard)\s*=\s*\{[\s\S]*?\}/g,
94
+ languages: ["javascript", "typescript"],
95
+ fix: "Never pass sensitive data as props to client components. Keep secrets server-side.",
96
+ fixCode: "// Keep sensitive data server-side\nexport default async function Page() {\n const secret = process.env.API_SECRET;\n const publicData = await fetchData(secret);\n return <ClientComponent data={publicData} />;\n}",
97
+ compliance: ["SOC2:CC6.1", "HIPAA:§164.312(a)"],
98
+ },
99
+ {
100
+ id: "VG408",
101
+ name: "Unsafe innerHTML Usage",
102
+ severity: "high",
103
+ owasp: "A03:2025 Injection",
104
+ description: "Using dangerouslySetInnerHTML renders unescaped HTML, which can lead to XSS if the content includes user input. This is a security rule detector — it flags vulnerable code patterns.",
105
+ pattern: /dangerouslySetInnerHTML\s*=\s*\{\s*\{\s*__html\s*:/g,
106
+ languages: ["javascript", "typescript"],
107
+ fix: "Sanitize HTML with DOMPurify before rendering, or use a markdown renderer instead.",
108
+ fixCode: '// Use a sanitizer library\nimport DOMPurify from "dompurify";\nconst clean = DOMPurify.sanitize(content);\n\n// Or use a markdown renderer\nimport ReactMarkdown from "react-markdown";\n<ReactMarkdown>{content}</ReactMarkdown>',
109
+ compliance: ["SOC2:CC7.1", "PCI-DSS:Req6.5.7"],
110
+ },
111
+ {
112
+ id: "VG409",
113
+ name: "Open Redirect via User Input",
114
+ severity: "medium",
115
+ owasp: "A01:2025 Broken Access Control",
116
+ description: "redirect() or NextResponse.redirect() uses user-controlled input (searchParams, query) which can redirect users to malicious sites.",
117
+ pattern: /redirect\s*\(\s*(?:searchParams|params|req\.query|request\.url|url|query)\s*[\.\[]/g,
118
+ languages: ["javascript", "typescript"],
119
+ fix: "Validate redirect URLs against an allowlist of trusted domains.",
120
+ fixCode: '// Validate redirect URL\nconst ALLOWED_HOSTS = ["example.com"];\nconst target = searchParams.get("next") ?? "/";\ntry {\n const url = new URL(target, request.url);\n if (!ALLOWED_HOSTS.includes(url.hostname)) redirect("/");\n redirect(url.pathname);\n} catch {\n redirect("/");\n}',
121
+ compliance: ["SOC2:CC6.6"],
122
+ },
123
+ {
124
+ id: "VG410",
125
+ name: "Unauthorized Cache Revalidation",
126
+ severity: "medium",
127
+ owasp: "A01:2025 Broken Access Control",
128
+ description: "revalidateTag() or revalidatePath() is called in a route handler without authentication check. Anyone could trigger cache invalidation.",
129
+ pattern: /(?:GET|POST|PUT|DELETE)\s*\([\s\S]*?(?:revalidateTag|revalidatePath)\s*\([\s\S]*?(?![\s\S]*?(?:auth\s*\(|getServerSession|currentUser))/g,
130
+ languages: ["javascript", "typescript"],
131
+ fix: "Protect revalidation endpoints with authentication or a secret token.",
132
+ fixCode: 'import { auth } from "@clerk/nextjs/server";\n\nexport async function POST(req: Request) {\n const { userId } = await auth();\n if (!userId) return new Response("Unauthorized", { status: 401 });\n revalidateTag("posts");\n return Response.json({ revalidated: true });\n}',
133
+ compliance: ["SOC2:CC6.6"],
134
+ },
135
+ {
136
+ id: "VG411",
137
+ name: "NEXT_PUBLIC_ Secret Leak",
138
+ severity: "critical",
139
+ owasp: "A07:2025 Sensitive Data Exposure",
140
+ description: "Environment variable prefixed with NEXT_PUBLIC_ contains a secret keyword (SECRET, KEY, PASSWORD, TOKEN). NEXT_PUBLIC_ variables are embedded in the client bundle and visible to anyone.",
141
+ pattern: /NEXT_PUBLIC_\w*(?:SECRET|_KEY|PASSWORD|TOKEN|PRIVATE|CREDENTIAL)\w*\s*=/gi,
142
+ languages: ["javascript", "typescript", "shell"],
143
+ fix: "Remove NEXT_PUBLIC_ prefix from secret variables. Access them only server-side.",
144
+ fixCode: "# .env.local — WRONG\n# NEXT_PUBLIC_SECRET_KEY=sk_live_xxx\n\n# .env.local — CORRECT\nSECRET_KEY=sk_live_xxx\n# Access server-side only: process.env.SECRET_KEY",
145
+ compliance: ["SOC2:CC6.1", "PCI-DSS:Req2.3", "HIPAA:§164.312(a)"],
146
+ },
147
+ ];
148
+ //# sourceMappingURL=nextjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs.js","sourceRoot":"","sources":["../../../src/data/rules/nextjs.ts"],"names":[],"mappings":"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"}