guardvibe 0.4.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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +205 -0
  3. package/build/cli.d.ts +3 -0
  4. package/build/cli.d.ts.map +1 -0
  5. package/build/cli.js +118 -0
  6. package/build/cli.js.map +1 -0
  7. package/build/data/framework-guides.d.ts +8 -0
  8. package/build/data/framework-guides.d.ts.map +1 -0
  9. package/build/data/framework-guides.js +500 -0
  10. package/build/data/framework-guides.js.map +1 -0
  11. package/build/data/owasp-rules.d.ts +12 -0
  12. package/build/data/owasp-rules.d.ts.map +1 -0
  13. package/build/data/owasp-rules.js +469 -0
  14. package/build/data/owasp-rules.js.map +1 -0
  15. package/build/data/rules/core.d.ts +3 -0
  16. package/build/data/rules/core.d.ts.map +1 -0
  17. package/build/data/rules/core.js +245 -0
  18. package/build/data/rules/core.js.map +1 -0
  19. package/build/data/rules/go.d.ts +3 -0
  20. package/build/data/rules/go.d.ts.map +1 -0
  21. package/build/data/rules/go.js +64 -0
  22. package/build/data/rules/go.js.map +1 -0
  23. package/build/data/rules/index.d.ts +3 -0
  24. package/build/data/rules/index.d.ts.map +1 -0
  25. package/build/data/rules/index.js +13 -0
  26. package/build/data/rules/index.js.map +1 -0
  27. package/build/data/rules/java.d.ts +3 -0
  28. package/build/data/rules/java.d.ts.map +1 -0
  29. package/build/data/rules/java.js +64 -0
  30. package/build/data/rules/java.js.map +1 -0
  31. package/build/data/rules/php.d.ts +3 -0
  32. package/build/data/rules/php.d.ts.map +1 -0
  33. package/build/data/rules/php.js +54 -0
  34. package/build/data/rules/php.js.map +1 -0
  35. package/build/data/rules/ruby.d.ts +3 -0
  36. package/build/data/rules/ruby.d.ts.map +1 -0
  37. package/build/data/rules/ruby.js +54 -0
  38. package/build/data/rules/ruby.js.map +1 -0
  39. package/build/data/rules/types.d.ts +11 -0
  40. package/build/data/rules/types.d.ts.map +1 -0
  41. package/build/data/rules/types.js +2 -0
  42. package/build/data/rules/types.js.map +1 -0
  43. package/build/data/secret-patterns.d.ts +9 -0
  44. package/build/data/secret-patterns.d.ts.map +1 -0
  45. package/build/data/secret-patterns.js +87 -0
  46. package/build/data/secret-patterns.js.map +1 -0
  47. package/build/index.d.ts +3 -0
  48. package/build/index.d.ts.map +1 -0
  49. package/build/index.js +117 -0
  50. package/build/index.js.map +1 -0
  51. package/build/tools/check-code.d.ts +9 -0
  52. package/build/tools/check-code.d.ts.map +1 -0
  53. package/build/tools/check-code.js +125 -0
  54. package/build/tools/check-code.js.map +1 -0
  55. package/build/tools/check-deps.d.ts +8 -0
  56. package/build/tools/check-deps.d.ts.map +1 -0
  57. package/build/tools/check-deps.js +57 -0
  58. package/build/tools/check-deps.js.map +1 -0
  59. package/build/tools/check-project.d.ts +7 -0
  60. package/build/tools/check-project.d.ts.map +1 -0
  61. package/build/tools/check-project.js +134 -0
  62. package/build/tools/check-project.js.map +1 -0
  63. package/build/tools/get-security-docs.d.ts +2 -0
  64. package/build/tools/get-security-docs.d.ts.map +1 -0
  65. package/build/tools/get-security-docs.js +61 -0
  66. package/build/tools/get-security-docs.js.map +1 -0
  67. package/build/tools/scan-dependencies.d.ts +2 -0
  68. package/build/tools/scan-dependencies.d.ts.map +1 -0
  69. package/build/tools/scan-dependencies.js +69 -0
  70. package/build/tools/scan-dependencies.js.map +1 -0
  71. package/build/tools/scan-directory.d.ts +2 -0
  72. package/build/tools/scan-directory.d.ts.map +1 -0
  73. package/build/tools/scan-directory.js +120 -0
  74. package/build/tools/scan-directory.js.map +1 -0
  75. package/build/tools/scan-secrets.d.ts +11 -0
  76. package/build/tools/scan-secrets.d.ts.map +1 -0
  77. package/build/tools/scan-secrets.js +150 -0
  78. package/build/tools/scan-secrets.js.map +1 -0
  79. package/build/utils/manifest-parser.d.ts +7 -0
  80. package/build/utils/manifest-parser.d.ts.map +1 -0
  81. package/build/utils/manifest-parser.js +102 -0
  82. package/build/utils/manifest-parser.js.map +1 -0
  83. package/build/utils/osv-client.d.ts +37 -0
  84. package/build/utils/osv-client.d.ts.map +1 -0
  85. package/build/utils/osv-client.js +78 -0
  86. package/build/utils/osv-client.js.map +1 -0
  87. package/package.json +46 -0
@@ -0,0 +1,61 @@
1
+ import { frameworkGuides } from "../data/framework-guides.js";
2
+ export function getSecurityDocs(topic) {
3
+ const normalizedTopic = topic.toLowerCase().trim();
4
+ // Try exact topic match first
5
+ const exactMatch = frameworkGuides.find((guide) => guide.topic === normalizedTopic);
6
+ if (exactMatch)
7
+ return exactMatch.content;
8
+ // Try keyword match
9
+ const keywordMatches = frameworkGuides
10
+ .map((guide) => {
11
+ const score = guide.keywords.reduce((acc, keyword) => {
12
+ if (normalizedTopic.includes(keyword))
13
+ return acc + 2;
14
+ if (keyword.includes(normalizedTopic))
15
+ return acc + 1;
16
+ return acc;
17
+ }, 0);
18
+ return { guide, score };
19
+ })
20
+ .filter((m) => m.score > 0)
21
+ .sort((a, b) => b.score - a.score);
22
+ if (keywordMatches.length > 0) {
23
+ // Return the best match, or multiple if scores are close
24
+ const best = keywordMatches[0];
25
+ const results = keywordMatches.filter((m) => m.score >= best.score * 0.7);
26
+ if (results.length === 1) {
27
+ return results[0].guide.content;
28
+ }
29
+ // Multiple relevant guides
30
+ return [
31
+ `# Security Guides for "${topic}"`,
32
+ ``,
33
+ `Found ${results.length} relevant guides:`,
34
+ ``,
35
+ ...results.map((r) => `---\n\n${r.guide.content}`),
36
+ ].join("\n");
37
+ }
38
+ // No match - return available topics
39
+ const availableTopics = frameworkGuides
40
+ .map((g) => `- **${g.topic}**: ${g.title}`)
41
+ .join("\n");
42
+ return [
43
+ `# No Guide Found for "${topic}"`,
44
+ ``,
45
+ `I don't have a specific security guide for that topic yet.`,
46
+ ``,
47
+ `## Available Topics:`,
48
+ availableTopics,
49
+ ``,
50
+ `## General Security Tips:`,
51
+ `1. Validate all user input with schemas (zod, joi, pydantic)`,
52
+ `2. Use parameterized queries for database access`,
53
+ `3. Hash passwords with bcrypt (12+ salt rounds)`,
54
+ `4. Set security headers (helmet for Express)`,
55
+ `5. Keep dependencies updated (npm audit)`,
56
+ `6. Use environment variables for secrets`,
57
+ `7. Add rate limiting to auth endpoints`,
58
+ `8. Set secure cookie flags (httpOnly, secure, sameSite)`,
59
+ ].join("\n");
60
+ }
61
+ //# sourceMappingURL=get-security-docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-security-docs.js","sourceRoot":"","sources":["../../src/tools/get-security-docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAEnD,8BAA8B;IAC9B,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CACrC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,eAAe,CAC3C,CAAC;IACF,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC,OAAO,CAAC;IAE1C,oBAAoB;IACpB,MAAM,cAAc,GAAG,eAAe;SACnC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;YACnD,IAAI,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,OAAO,GAAG,GAAG,CAAC,CAAC;YACtD,IAAI,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;gBAAE,OAAO,GAAG,GAAG,CAAC,CAAC;YACtD,OAAO,GAAG,CAAC;QACb,CAAC,EAAE,CAAC,CAAC,CAAC;QACN,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;SAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAErC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,yDAAyD;QACzD,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,GAAG,CACnC,CAAC;QAEF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QAClC,CAAC;QAED,2BAA2B;QAC3B,OAAO;YACL,0BAA0B,KAAK,GAAG;YAClC,EAAE;YACF,SAAS,OAAO,CAAC,MAAM,mBAAmB;YAC1C,EAAE;YACF,GAAG,OAAO,CAAC,GAAG,CACZ,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CACnC;SACF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,qCAAqC;IACrC,MAAM,eAAe,GAAG,eAAe;SACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC;SAC1C,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;QACL,yBAAyB,KAAK,GAAG;QACjC,EAAE;QACF,4DAA4D;QAC5D,EAAE;QACF,sBAAsB;QACtB,eAAe;QACf,EAAE;QACF,2BAA2B;QAC3B,8DAA8D;QAC9D,kDAAkD;QAClD,iDAAiD;QACjD,8CAA8C;QAC9C,0CAA0C;QAC1C,0CAA0C;QAC1C,wCAAwC;QACxC,yDAAyD;KAC1D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function scanDependencies(manifestPath: string): Promise<string>;
2
+ //# sourceMappingURL=scan-dependencies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-dependencies.d.ts","sourceRoot":"","sources":["../../src/tools/scan-dependencies.ts"],"names":[],"mappings":"AAKA,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqE5E"}
@@ -0,0 +1,69 @@
1
+ import { readFileSync } from "fs";
2
+ import { basename } from "path";
3
+ import { parseManifest } from "../utils/manifest-parser.js";
4
+ import { queryOsvBatch, formatVulnerability } from "../utils/osv-client.js";
5
+ export async function scanDependencies(manifestPath) {
6
+ let content;
7
+ try {
8
+ content = readFileSync(manifestPath, "utf-8");
9
+ }
10
+ catch {
11
+ return `# GuardVibe Dependency Report\n\nError: Could not read file: ${manifestPath}`;
12
+ }
13
+ const filename = basename(manifestPath);
14
+ let packages;
15
+ try {
16
+ packages = parseManifest(content, filename);
17
+ }
18
+ catch (e) {
19
+ const msg = e instanceof Error ? e.message : "Unknown error";
20
+ return `# GuardVibe Dependency Report\n\nError: ${msg}`;
21
+ }
22
+ if (packages.length === 0) {
23
+ return `# GuardVibe Dependency Report\n\nFile: ${manifestPath}\nPackages found: 0\n\nNo packages to check.`;
24
+ }
25
+ const lines = [
26
+ `# GuardVibe Dependency Report`,
27
+ ``,
28
+ `File: ${manifestPath}`,
29
+ `Packages checked: ${packages.length}`,
30
+ `Database: OSV (Google Open Source Vulnerabilities)`,
31
+ ``,
32
+ `---`,
33
+ ``,
34
+ ];
35
+ let vulnResults;
36
+ try {
37
+ vulnResults = await queryOsvBatch(packages);
38
+ }
39
+ catch {
40
+ lines.push(`Error: Could not reach OSV API. Check your network connection.`);
41
+ return lines.join("\n");
42
+ }
43
+ let totalVulns = 0;
44
+ const criticalPackages = [];
45
+ for (const pkg of packages) {
46
+ const key = `${pkg.name}@${pkg.version}`;
47
+ const vulns = vulnResults.get(key) || [];
48
+ if (vulns.length === 0)
49
+ continue;
50
+ totalVulns += vulns.length;
51
+ criticalPackages.push(key);
52
+ lines.push(`## ${key} (${pkg.ecosystem}) — ${vulns.length} vulnerabilities`, ``);
53
+ for (const vuln of vulns) {
54
+ lines.push(formatVulnerability(vuln), ``);
55
+ }
56
+ }
57
+ lines.push(`---`, ``, `## Summary`, ``);
58
+ if (totalVulns === 0) {
59
+ lines.push(`All ${packages.length} packages are clean. No known vulnerabilities found.`);
60
+ }
61
+ else {
62
+ lines.push(`**${totalVulns} vulnerabilities** found in ${criticalPackages.length} packages:`, ``);
63
+ for (const pkg of criticalPackages)
64
+ lines.push(`- ${pkg}`);
65
+ lines.push(``, `**Action:** Update affected packages to their fixed versions.`);
66
+ }
67
+ return lines.join("\n");
68
+ }
69
+ //# sourceMappingURL=scan-dependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-dependencies.js","sourceRoot":"","sources":["../../src/tools/scan-dependencies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function scanDirectory(path: string, recursive?: boolean, exclude?: string[]): string;
2
+ //# sourceMappingURL=scan-directory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-directory.d.ts","sourceRoot":"","sources":["../../src/tools/scan-directory.ts"],"names":[],"mappings":"AAqDA,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,OAAc,EACzB,OAAO,GAAE,MAAM,EAAO,GACrB,MAAM,CA2FR"}
@@ -0,0 +1,120 @@
1
+ import { readdirSync, readFileSync, statSync } from "fs";
2
+ import { join, extname } from "path";
3
+ import { analyzeCode } from "./check-code.js";
4
+ const DEFAULT_EXCLUDES = new Set([
5
+ "node_modules", ".git", "build", "dist", "vendor", "__pycache__",
6
+ ".next", ".nuxt", ".svelte-kit", "target", "bin", "obj",
7
+ "coverage", ".turbo", ".venv", "venv",
8
+ ]);
9
+ const EXTENSION_MAP = {
10
+ ".js": "javascript", ".jsx": "javascript", ".mjs": "javascript", ".cjs": "javascript",
11
+ ".ts": "typescript", ".tsx": "typescript", ".mts": "typescript", ".cts": "typescript",
12
+ ".py": "python", ".go": "go", ".java": "java",
13
+ ".php": "php", ".rb": "ruby", ".html": "html",
14
+ ".sql": "sql", ".sh": "shell", ".bash": "shell",
15
+ };
16
+ const MAX_FILE_SIZE = 500 * 1024; // 500KB
17
+ function walkDirectory(dir, recursive, excludes, results) {
18
+ let entries;
19
+ try {
20
+ entries = readdirSync(dir, { withFileTypes: true });
21
+ }
22
+ catch {
23
+ return;
24
+ }
25
+ for (const entry of entries) {
26
+ if (excludes.has(entry.name))
27
+ continue;
28
+ const fullPath = join(dir, entry.name);
29
+ if (entry.isDirectory() && recursive) {
30
+ walkDirectory(fullPath, recursive, excludes, results);
31
+ }
32
+ else if (entry.isFile()) {
33
+ const ext = extname(entry.name).toLowerCase();
34
+ if (EXTENSION_MAP[ext]) {
35
+ results.push(fullPath);
36
+ }
37
+ }
38
+ }
39
+ }
40
+ export function scanDirectory(path, recursive = true, exclude = []) {
41
+ const excludes = new Set([...DEFAULT_EXCLUDES, ...exclude]);
42
+ const filePaths = [];
43
+ walkDirectory(path, recursive, excludes, filePaths);
44
+ const scanResults = [];
45
+ const skippedFiles = [];
46
+ for (const filePath of filePaths) {
47
+ try {
48
+ const stat = statSync(filePath);
49
+ if (stat.size > MAX_FILE_SIZE) {
50
+ skippedFiles.push(`${filePath} (too large: ${Math.round(stat.size / 1024)}KB)`);
51
+ continue;
52
+ }
53
+ const content = readFileSync(filePath, "utf-8");
54
+ const ext = extname(filePath).toLowerCase();
55
+ const language = EXTENSION_MAP[ext];
56
+ if (!language)
57
+ continue;
58
+ const findings = analyzeCode(content, language);
59
+ if (findings.length > 0) {
60
+ scanResults.push({ path: filePath, findings });
61
+ }
62
+ }
63
+ catch {
64
+ skippedFiles.push(`${filePath} (read error)`);
65
+ }
66
+ }
67
+ // Scoring
68
+ const allFindings = scanResults.flatMap(r => r.findings);
69
+ const totalCritical = allFindings.filter(f => f.rule.severity === "critical").length;
70
+ const totalHigh = allFindings.filter(f => f.rule.severity === "high").length;
71
+ const totalMedium = allFindings.filter(f => f.rule.severity === "medium").length;
72
+ const totalIssues = totalCritical + totalHigh + totalMedium;
73
+ const score = Math.max(0, Math.min(100, 100 - totalCritical * 25 - totalHigh * 10 - totalMedium * 5));
74
+ const grade = score >= 90 ? "A" : score >= 75 ? "B" : score >= 60 ? "C" : score >= 40 ? "D" : "F";
75
+ const lines = [
76
+ `# GuardVibe Directory Security Report`,
77
+ ``,
78
+ `Directory: ${path}`,
79
+ `Files scanned: ${filePaths.length - skippedFiles.length}`,
80
+ `Total issues: ${totalIssues}`,
81
+ `Security Score: ${grade} (${score}/100)`,
82
+ ``,
83
+ ];
84
+ if (totalIssues > 0) {
85
+ lines.push(`## Summary`, ``, `| Severity | Count |`, `|----------|-------|`);
86
+ if (totalCritical > 0)
87
+ lines.push(`| Critical | ${totalCritical} |`);
88
+ if (totalHigh > 0)
89
+ lines.push(`| High | ${totalHigh} |`);
90
+ if (totalMedium > 0)
91
+ lines.push(`| Medium | ${totalMedium} |`);
92
+ lines.push(``);
93
+ const severityOrder = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
94
+ const topIssues = scanResults.flatMap(r => r.findings.map(f => ({
95
+ text: `[${f.rule.severity.toUpperCase()}] ${f.rule.name} in ${r.path} (${f.rule.id})`,
96
+ order: severityOrder[f.rule.severity] ?? 99,
97
+ }))).sort((a, b) => a.order - b.order).slice(0, 10);
98
+ lines.push(`## Top Issues`);
99
+ topIssues.forEach((issue, i) => lines.push(`${i + 1}. ${issue.text}`));
100
+ lines.push(``, `---`, ``);
101
+ for (const result of scanResults) {
102
+ lines.push(`## File: ${result.path} (${result.findings.length} issues)`, ``);
103
+ for (const f of result.findings) {
104
+ const icon = f.rule.severity.toUpperCase();
105
+ lines.push(`### [${icon}] ${f.rule.name} (${f.rule.id})`, `**Line:** ~${f.line} | **Match:** \`${f.match}\``, `${f.rule.description}`, `**Fix:** ${f.rule.fix}`, ``);
106
+ }
107
+ lines.push(`---`, ``);
108
+ }
109
+ }
110
+ else {
111
+ lines.push(`## No Issues Found`, ``, `All files passed security checks.`);
112
+ }
113
+ if (skippedFiles.length > 0) {
114
+ lines.push(``, `**Skipped files:**`);
115
+ for (const s of skippedFiles)
116
+ lines.push(`- ${s}`);
117
+ }
118
+ return lines.join("\n");
119
+ }
120
+ //# sourceMappingURL=scan-directory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-directory.js","sourceRoot":"","sources":["../../src/tools/scan-directory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface SecretFinding {
2
+ provider: string;
3
+ severity: "critical" | "high" | "medium";
4
+ file: string;
5
+ line: number;
6
+ match: string;
7
+ fix: string;
8
+ }
9
+ export declare function scanContent(content: string, filename: string): SecretFinding[];
10
+ export declare function scanSecrets(path: string, recursive?: boolean): string;
11
+ //# sourceMappingURL=scan-secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-secrets.d.ts","sourceRoot":"","sources":["../../src/tools/scan-secrets.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CA8C9E;AA4BD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,OAAc,GAAG,MAAM,CAgF3E"}
@@ -0,0 +1,150 @@
1
+ import { readdirSync, readFileSync, statSync } from "fs";
2
+ import { join, extname, basename } from "path";
3
+ import { secretPatterns, calculateEntropy } from "../data/secret-patterns.js";
4
+ export function scanContent(content, filename) {
5
+ const findings = [];
6
+ for (const sp of secretPatterns) {
7
+ sp.pattern.lastIndex = 0;
8
+ let match;
9
+ while ((match = sp.pattern.exec(content)) !== null) {
10
+ const beforeMatch = content.substring(0, match.index);
11
+ const lineNumber = beforeMatch.split("\n").length;
12
+ findings.push({
13
+ provider: sp.provider,
14
+ severity: sp.severity,
15
+ file: filename,
16
+ line: lineNumber,
17
+ match: match[0].substring(0, 40) + (match[0].length > 40 ? "..." : ""),
18
+ fix: sp.fix,
19
+ });
20
+ }
21
+ }
22
+ // Entropy-based detection for .env files
23
+ if (basename(filename).startsWith(".env")) {
24
+ const lines = content.split("\n");
25
+ for (let i = 0; i < lines.length; i++) {
26
+ const line = lines[i].trim();
27
+ if (!line || line.startsWith("#"))
28
+ continue;
29
+ const eqIdx = line.indexOf("=");
30
+ if (eqIdx === -1)
31
+ continue;
32
+ const value = line.substring(eqIdx + 1).replace(/^['"]|['"]$/g, "");
33
+ if (value.length >= 20 && calculateEntropy(value) > 4.5) {
34
+ const alreadyFound = findings.some(f => f.line === i + 1);
35
+ if (!alreadyFound) {
36
+ findings.push({
37
+ provider: "High-Entropy Secret",
38
+ severity: "high",
39
+ file: filename,
40
+ line: i + 1,
41
+ match: line.substring(0, 40) + "...",
42
+ fix: "This looks like a secret (high entropy). Ensure this file is in .gitignore.",
43
+ });
44
+ }
45
+ }
46
+ }
47
+ }
48
+ return findings;
49
+ }
50
+ function walkForSecrets(dir, recursive, results) {
51
+ let entries;
52
+ try {
53
+ entries = readdirSync(dir, { withFileTypes: true });
54
+ }
55
+ catch {
56
+ return;
57
+ }
58
+ for (const entry of entries) {
59
+ if (entry.name === "node_modules" || entry.name === ".git" || entry.name === "build" || entry.name === "dist")
60
+ continue;
61
+ const fullPath = join(dir, entry.name);
62
+ if (entry.isDirectory() && recursive) {
63
+ walkForSecrets(fullPath, recursive, results);
64
+ }
65
+ else if (entry.isFile()) {
66
+ const name = entry.name;
67
+ const ext = extname(name).toLowerCase();
68
+ // Check env files and config files
69
+ if (name.startsWith(".env") || [".yml", ".yaml", ".toml", ".json", ".cfg", ".ini", ".conf"].includes(ext)) {
70
+ results.push(fullPath);
71
+ }
72
+ // Also scan source files
73
+ if ([".ts", ".js", ".py", ".go", ".java", ".php", ".rb"].includes(ext)) {
74
+ results.push(fullPath);
75
+ }
76
+ }
77
+ }
78
+ }
79
+ export function scanSecrets(path, recursive = true) {
80
+ const filePaths = [];
81
+ try {
82
+ const stat = statSync(path);
83
+ if (stat.isFile()) {
84
+ filePaths.push(path);
85
+ }
86
+ else {
87
+ walkForSecrets(path, recursive, filePaths);
88
+ }
89
+ }
90
+ catch {
91
+ return `# GuardVibe Secret Scan Report\n\nError: Could not access path: ${path}`;
92
+ }
93
+ const uniquePaths = [...new Set(filePaths)];
94
+ const allFindings = [];
95
+ for (const filePath of uniquePaths) {
96
+ try {
97
+ const stat = statSync(filePath);
98
+ if (stat.size > 500 * 1024)
99
+ continue;
100
+ const content = readFileSync(filePath, "utf-8");
101
+ const findings = scanContent(content, filePath);
102
+ allFindings.push(...findings);
103
+ }
104
+ catch { /* skip */ }
105
+ }
106
+ // Check .gitignore for .env coverage
107
+ let gitignoreContent = "";
108
+ try {
109
+ const gitignorePath = statSync(path).isDirectory() ? join(path, ".gitignore") : ".gitignore";
110
+ gitignoreContent = readFileSync(gitignorePath, "utf-8");
111
+ }
112
+ catch { /* no gitignore */ }
113
+ const envFiles = uniquePaths.filter(f => basename(f).startsWith(".env"));
114
+ for (const envFile of envFiles) {
115
+ const envName = basename(envFile);
116
+ if (!gitignoreContent.includes(envName) && !gitignoreContent.includes(".env*") && !gitignoreContent.includes(".env")) {
117
+ allFindings.push({
118
+ provider: ".env not in .gitignore",
119
+ severity: "critical",
120
+ file: envFile,
121
+ line: 0,
122
+ match: `${envName} is not listed in .gitignore`,
123
+ fix: `Add '${envName}' or '.env*' to .gitignore immediately.`,
124
+ });
125
+ }
126
+ }
127
+ // Format report
128
+ const lines = [
129
+ `# GuardVibe Secret Scan Report`,
130
+ ``,
131
+ `Files scanned: ${uniquePaths.length}`,
132
+ `Secrets found: ${allFindings.length}`,
133
+ ];
134
+ if (allFindings.length > 0) {
135
+ const critCount = allFindings.filter(f => f.severity === "critical").length;
136
+ const highCount = allFindings.filter(f => f.severity === "high").length;
137
+ lines.push(`Risk Level: ${critCount > 0 ? "Critical" : highCount > 0 ? "High" : "Medium"}`);
138
+ lines.push(``, `---`, ``, `## Findings`, ``);
139
+ const order = { critical: 0, high: 1, medium: 2 };
140
+ allFindings.sort((a, b) => order[a.severity] - order[b.severity]);
141
+ for (const f of allFindings) {
142
+ lines.push(`### [${f.severity.toUpperCase()}] ${f.provider}`, `**File:** ${f.file}${f.line > 0 ? `:${f.line}` : ""}`, `**Match:** \`${f.match}\``, `**Fix:** ${f.fix}`, ``);
143
+ }
144
+ }
145
+ else {
146
+ lines.push(`Risk Level: None`, ``, `No secrets detected. Good job keeping your code clean!`);
147
+ }
148
+ return lines.join("\n");
149
+ }
150
+ //# sourceMappingURL=scan-secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-secrets.js","sourceRoot":"","sources":["../../src/tools/scan-secrets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface ParsedPackage {
2
+ name: string;
3
+ version: string;
4
+ ecosystem: string;
5
+ }
6
+ export declare function parseManifest(content: string, filename: string): ParsedPackage[];
7
+ //# sourceMappingURL=manifest-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-parser.d.ts","sourceRoot":"","sources":["../../src/utils/manifest-parser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CAWhF"}
@@ -0,0 +1,102 @@
1
+ export function parseManifest(content, filename) {
2
+ const lower = filename.toLowerCase();
3
+ if (lower === "package-lock.json")
4
+ return parsePackageLock(content);
5
+ if (lower === "package.json")
6
+ return parsePackageJson(content);
7
+ if (lower === "requirements.txt")
8
+ return parseRequirementsTxt(content);
9
+ if (lower === "go.mod")
10
+ return parseGoMod(content);
11
+ if (lower === "gemfile.lock")
12
+ return parseGemfileLock(content);
13
+ if (lower === "cargo.lock")
14
+ return parseCargoLock(content);
15
+ throw new Error(`Unsupported manifest format: ${filename}`);
16
+ }
17
+ function parsePackageJson(content) {
18
+ const pkg = JSON.parse(content);
19
+ const packages = [];
20
+ for (const [name, ver] of Object.entries(pkg.dependencies || {})) {
21
+ const version = String(ver).replace(/^[\^~>=<]*/g, "");
22
+ if (version)
23
+ packages.push({ name, version, ecosystem: "npm" });
24
+ }
25
+ for (const [name, ver] of Object.entries(pkg.devDependencies || {})) {
26
+ const version = String(ver).replace(/^[\^~>=<]*/g, "");
27
+ if (version)
28
+ packages.push({ name, version, ecosystem: "npm" });
29
+ }
30
+ return packages;
31
+ }
32
+ function parsePackageLock(content) {
33
+ const lock = JSON.parse(content);
34
+ const packages = [];
35
+ if (lock.packages) {
36
+ for (const [path, info] of Object.entries(lock.packages)) {
37
+ if (path === "")
38
+ continue;
39
+ const pkg = info;
40
+ if (!pkg.version)
41
+ continue;
42
+ const name = path.replace(/^node_modules\//, "");
43
+ packages.push({ name, version: pkg.version, ecosystem: "npm" });
44
+ }
45
+ }
46
+ return packages;
47
+ }
48
+ function parseRequirementsTxt(content) {
49
+ return content.split("\n")
50
+ .map(line => line.trim())
51
+ .filter(line => line && !line.startsWith("#") && !line.startsWith("-"))
52
+ .map(line => {
53
+ const match = line.match(/^([a-zA-Z0-9_.-]+)==([a-zA-Z0-9_.]+)/);
54
+ if (!match)
55
+ return null;
56
+ return { name: match[1], version: match[2], ecosystem: "PyPI" };
57
+ })
58
+ .filter((p) => p !== null);
59
+ }
60
+ function parseGoMod(content) {
61
+ const packages = [];
62
+ const requireBlock = content.match(/require\s*\(([\s\S]*?)\)/);
63
+ const lines = requireBlock ? requireBlock[1].split("\n") : [];
64
+ const singleRequires = content.matchAll(/require\s+(\S+)\s+v?(\S+)/g);
65
+ for (const m of singleRequires) {
66
+ packages.push({ name: m[1], version: m[2].replace(/^v/, ""), ecosystem: "Go" });
67
+ }
68
+ for (const line of lines) {
69
+ const match = line.trim().match(/^(\S+)\s+v?(\S+)/);
70
+ if (match && !match[1].startsWith("//")) {
71
+ packages.push({ name: match[1], version: match[2].replace(/^v/, ""), ecosystem: "Go" });
72
+ }
73
+ }
74
+ return packages;
75
+ }
76
+ function parseGemfileLock(content) {
77
+ const packages = [];
78
+ const specsSection = content.match(/specs:\n([\s\S]*?)(?:\n\S|\n\n|$)/);
79
+ if (!specsSection)
80
+ return packages;
81
+ const lines = specsSection[1].split("\n");
82
+ for (const line of lines) {
83
+ const match = line.match(/^\s{4}(\S+)\s+\(([^)]+)\)/);
84
+ if (match) {
85
+ packages.push({ name: match[1], version: match[2], ecosystem: "RubyGems" });
86
+ }
87
+ }
88
+ return packages;
89
+ }
90
+ function parseCargoLock(content) {
91
+ const packages = [];
92
+ const blocks = content.split("[[package]]");
93
+ for (const block of blocks.slice(1)) {
94
+ const name = block.match(/name\s*=\s*"([^"]+)"/)?.[1];
95
+ const version = block.match(/version\s*=\s*"([^"]+)"/)?.[1];
96
+ if (name && version) {
97
+ packages.push({ name, version, ecosystem: "crates.io" });
98
+ }
99
+ }
100
+ return packages;
101
+ }
102
+ //# sourceMappingURL=manifest-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-parser.js","sourceRoot":"","sources":["../../src/utils/manifest-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ interface OsvVulnerability {
2
+ id: string;
3
+ summary: string;
4
+ details?: string;
5
+ severity?: Array<{
6
+ type: string;
7
+ score: string;
8
+ }>;
9
+ affected?: Array<{
10
+ package?: {
11
+ name: string;
12
+ ecosystem: string;
13
+ };
14
+ ranges?: Array<{
15
+ type: string;
16
+ events: Array<{
17
+ introduced?: string;
18
+ fixed?: string;
19
+ }>;
20
+ }>;
21
+ }>;
22
+ references?: Array<{
23
+ type: string;
24
+ url: string;
25
+ }>;
26
+ }
27
+ export declare function queryOsv(name: string, version: string, ecosystem: string): Promise<OsvVulnerability[]>;
28
+ interface BatchQuery {
29
+ name: string;
30
+ version: string;
31
+ ecosystem: string;
32
+ }
33
+ export declare function queryOsvBatch(packages: BatchQuery[]): Promise<Map<string, any[]>>;
34
+ export declare function normalizeSeverity(vuln: any): string;
35
+ export declare function formatVulnerability(vuln: OsvVulnerability): string;
36
+ export {};
37
+ //# sourceMappingURL=osv-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osv-client.d.ts","sourceRoot":"","sources":["../../src/utils/osv-client.ts"],"names":[],"mappings":"AAAA,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,OAAO,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;QAC9C,MAAM,CAAC,EAAE,KAAK,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,MAAM,EAAE,KAAK,CAAC;gBAAE,UAAU,CAAC,EAAE,MAAM,CAAC;gBAAC,KAAK,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SACxD,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAMD,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAiB7B;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,UAAU,EAAE,GACrB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAwB7B;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CASnD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CA4BlE"}