guardrail-security 1.0.2 → 2.0.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 (60) hide show
  1. package/dist/sbom/generator.d.ts +42 -0
  2. package/dist/sbom/generator.d.ts.map +1 -1
  3. package/dist/sbom/generator.js +168 -7
  4. package/dist/secrets/allowlist.d.ts +38 -0
  5. package/dist/secrets/allowlist.d.ts.map +1 -0
  6. package/dist/secrets/allowlist.js +131 -0
  7. package/dist/secrets/config-loader.d.ts +25 -0
  8. package/dist/secrets/config-loader.d.ts.map +1 -0
  9. package/dist/secrets/config-loader.js +103 -0
  10. package/dist/secrets/contextual-risk.d.ts +19 -0
  11. package/dist/secrets/contextual-risk.d.ts.map +1 -0
  12. package/dist/secrets/contextual-risk.js +88 -0
  13. package/dist/secrets/git-scanner.d.ts +29 -0
  14. package/dist/secrets/git-scanner.d.ts.map +1 -0
  15. package/dist/secrets/git-scanner.js +109 -0
  16. package/dist/secrets/guardian.d.ts +70 -57
  17. package/dist/secrets/guardian.d.ts.map +1 -1
  18. package/dist/secrets/guardian.js +531 -258
  19. package/dist/secrets/index.d.ts +4 -0
  20. package/dist/secrets/index.d.ts.map +1 -1
  21. package/dist/secrets/index.js +11 -1
  22. package/dist/secrets/patterns.d.ts +39 -10
  23. package/dist/secrets/patterns.d.ts.map +1 -1
  24. package/dist/secrets/patterns.js +129 -71
  25. package/dist/secrets/pre-commit.d.ts.map +1 -1
  26. package/dist/secrets/pre-commit.js +1 -1
  27. package/dist/secrets/vault-integration.d.ts.map +1 -1
  28. package/dist/secrets/vault-integration.js +1 -0
  29. package/dist/supply-chain/vulnerability-db.d.ts +89 -16
  30. package/dist/supply-chain/vulnerability-db.d.ts.map +1 -1
  31. package/dist/supply-chain/vulnerability-db.js +404 -115
  32. package/dist/utils/semver.d.ts +37 -0
  33. package/dist/utils/semver.d.ts.map +1 -0
  34. package/dist/utils/semver.js +109 -0
  35. package/package.json +17 -3
  36. package/src/__tests__/license/engine.test.ts +0 -250
  37. package/src/__tests__/supply-chain/typosquat.test.ts +0 -191
  38. package/src/attack-surface/analyzer.ts +0 -153
  39. package/src/attack-surface/index.ts +0 -5
  40. package/src/index.ts +0 -21
  41. package/src/languages/index.ts +0 -91
  42. package/src/languages/java-analyzer.ts +0 -490
  43. package/src/languages/python-analyzer.ts +0 -498
  44. package/src/license/compatibility-matrix.ts +0 -366
  45. package/src/license/engine.ts +0 -346
  46. package/src/license/index.ts +0 -6
  47. package/src/sbom/generator.ts +0 -355
  48. package/src/sbom/index.ts +0 -5
  49. package/src/secrets/guardian.ts +0 -468
  50. package/src/secrets/index.ts +0 -10
  51. package/src/secrets/patterns.ts +0 -186
  52. package/src/secrets/pre-commit.ts +0 -158
  53. package/src/secrets/vault-integration.ts +0 -360
  54. package/src/secrets/vault-providers.ts +0 -446
  55. package/src/supply-chain/detector.ts +0 -253
  56. package/src/supply-chain/index.ts +0 -11
  57. package/src/supply-chain/malicious-db.ts +0 -103
  58. package/src/supply-chain/script-analyzer.ts +0 -194
  59. package/src/supply-chain/typosquat.ts +0 -302
  60. package/src/supply-chain/vulnerability-db.ts +0 -386
@@ -1,490 +0,0 @@
1
- /**
2
- * Java Language Analyzer
3
- *
4
- * Security analysis for Java projects including:
5
- * - Maven pom.xml / Gradle build.gradle parsing
6
- * - Import analysis for detecting dangerous classes
7
- * - Secret detection patterns specific to Java
8
- * - Common vulnerability patterns (SQL injection, XXE, deserialization, etc.)
9
- */
10
-
11
- import { readFileSync, existsSync, readdirSync, statSync } from "fs";
12
- import { join } from "path";
13
-
14
- export interface JavaDependency {
15
- groupId: string;
16
- artifactId: string;
17
- version: string;
18
- scope?: string;
19
- source: "maven" | "gradle";
20
- }
21
-
22
- export interface JavaSecurityIssue {
23
- type: "vulnerability" | "secret" | "dangerous_import" | "code_pattern";
24
- severity: "low" | "medium" | "high" | "critical";
25
- file: string;
26
- line?: number;
27
- message: string;
28
- recommendation: string;
29
- cwe?: string;
30
- }
31
-
32
- export interface JavaAnalysisResult {
33
- projectPath: string;
34
- javaVersion?: string;
35
- buildTool: "maven" | "gradle" | "unknown";
36
- dependencies: JavaDependency[];
37
- securityIssues: JavaSecurityIssue[];
38
- summary: {
39
- totalDependencies: number;
40
- issuesBySeverity: Record<string, number>;
41
- };
42
- }
43
-
44
- // Dangerous Java imports
45
- const DANGEROUS_IMPORTS = [
46
- {
47
- pkg: "java.io.ObjectInputStream",
48
- reason: "Unsafe deserialization",
49
- severity: "critical" as const,
50
- cwe: "CWE-502",
51
- },
52
- {
53
- pkg: "java.lang.Runtime",
54
- reason: "Command execution",
55
- severity: "high" as const,
56
- cwe: "CWE-78",
57
- },
58
- {
59
- pkg: "java.lang.ProcessBuilder",
60
- reason: "Command execution",
61
- severity: "high" as const,
62
- cwe: "CWE-78",
63
- },
64
- {
65
- pkg: "javax.xml.parsers",
66
- reason: "Potential XXE vulnerability",
67
- severity: "medium" as const,
68
- cwe: "CWE-611",
69
- },
70
- {
71
- pkg: "org.xml.sax",
72
- reason: "Potential XXE vulnerability",
73
- severity: "medium" as const,
74
- cwe: "CWE-611",
75
- },
76
- {
77
- pkg: "java.security.MessageDigest",
78
- reason: "Verify secure algorithm usage",
79
- severity: "low" as const,
80
- cwe: "CWE-327",
81
- },
82
- ];
83
-
84
- // Java-specific secret patterns
85
- const JAVA_SECRET_PATTERNS = [
86
- { pattern: /(?:apiKey|API_KEY)\s*=\s*"[^"]{10,}"/g, type: "API Key" },
87
- {
88
- pattern: /(?:password|PASSWORD|passwd)\s*=\s*"[^"]{6,}"/g,
89
- type: "Password",
90
- },
91
- { pattern: /(?:secret|SECRET|secretKey)\s*=\s*"[^"]{10,}"/g, type: "Secret" },
92
- { pattern: /(?:token|TOKEN|accessToken)\s*=\s*"[^"]{10,}"/g, type: "Token" },
93
- {
94
- pattern: /(?:jdbc|JDBC):[^"]+password=[^"]+/g,
95
- type: "JDBC Connection String",
96
- },
97
- { pattern: /aws\.accessKeyId\s*=\s*"[^"]+"/g, type: "AWS Access Key" },
98
- { pattern: /aws\.secretKey\s*=\s*"[^"]+"/g, type: "AWS Secret Key" },
99
- ];
100
-
101
- // Vulnerability code patterns
102
- const VULNERABILITY_PATTERNS = [
103
- {
104
- pattern: /Statement\s+\w+\s*=.*createStatement\(\)/g,
105
- type: "SQL Injection",
106
- message: "Using Statement instead of PreparedStatement",
107
- severity: "critical" as const,
108
- cwe: "CWE-89",
109
- },
110
- {
111
- pattern: /executeQuery\s*\(\s*"[^"]*"\s*\+/g,
112
- type: "SQL Injection",
113
- message: "String concatenation in SQL query",
114
- severity: "critical" as const,
115
- cwe: "CWE-89",
116
- },
117
- {
118
- pattern: /Runtime\.getRuntime\(\)\.exec\s*\(/g,
119
- type: "Command Injection",
120
- message: "Runtime.exec() can be vulnerable to command injection",
121
- severity: "high" as const,
122
- cwe: "CWE-78",
123
- },
124
- {
125
- pattern: /new\s+ObjectInputStream\s*\(/g,
126
- type: "Unsafe Deserialization",
127
- message: "ObjectInputStream can deserialize malicious objects",
128
- severity: "critical" as const,
129
- cwe: "CWE-502",
130
- },
131
- {
132
- pattern: /DocumentBuilderFactory\.newInstance\(\)/g,
133
- type: "XXE Vulnerability",
134
- message: "XML parser may be vulnerable to XXE - disable external entities",
135
- severity: "high" as const,
136
- cwe: "CWE-611",
137
- },
138
- {
139
- pattern: /SAXParserFactory\.newInstance\(\)/g,
140
- type: "XXE Vulnerability",
141
- message: "SAX parser may be vulnerable to XXE - disable external entities",
142
- severity: "high" as const,
143
- cwe: "CWE-611",
144
- },
145
- {
146
- pattern: /MessageDigest\.getInstance\s*\(\s*"MD5"\s*\)/g,
147
- type: "Weak Cryptography",
148
- message: "MD5 is cryptographically broken",
149
- severity: "medium" as const,
150
- cwe: "CWE-327",
151
- },
152
- {
153
- pattern: /MessageDigest\.getInstance\s*\(\s*"SHA-?1"\s*\)/g,
154
- type: "Weak Cryptography",
155
- message: "SHA-1 is deprecated for security use",
156
- severity: "medium" as const,
157
- cwe: "CWE-327",
158
- },
159
- {
160
- pattern: /new\s+Random\s*\(\)/g,
161
- type: "Weak Random",
162
- message: "java.util.Random is not cryptographically secure",
163
- severity: "medium" as const,
164
- cwe: "CWE-330",
165
- },
166
- {
167
- pattern: /setAllowFileAccess\s*\(\s*true\s*\)/g,
168
- type: "WebView File Access",
169
- message: "WebView file access enabled",
170
- severity: "high" as const,
171
- cwe: "CWE-200",
172
- },
173
- {
174
- pattern: /TrustManager\s*\[\s*\]\s*\{[^}]*checkServerTrusted[^}]*\{\s*\}/g,
175
- type: "SSL/TLS Bypass",
176
- message: "Empty TrustManager bypasses SSL verification",
177
- severity: "critical" as const,
178
- cwe: "CWE-295",
179
- },
180
- ];
181
-
182
- export class JavaAnalyzer {
183
- /**
184
- * Analyze a Java project
185
- */
186
- async analyze(projectPath: string): Promise<JavaAnalysisResult> {
187
- const buildTool = this.detectBuildTool(projectPath);
188
- const dependencies = await this.extractDependencies(projectPath, buildTool);
189
- const securityIssues: JavaSecurityIssue[] = [];
190
-
191
- // Scan Java files for security issues
192
- const javaFiles = this.findJavaFiles(projectPath);
193
- for (const file of javaFiles) {
194
- const issues = this.scanFile(file);
195
- securityIssues.push(...issues);
196
- }
197
-
198
- // Get Java version if available
199
- const javaVersion = this.detectJavaVersion(projectPath);
200
-
201
- // Calculate summary
202
- const issuesBySeverity: Record<string, number> = {
203
- critical: 0,
204
- high: 0,
205
- medium: 0,
206
- low: 0,
207
- };
208
- for (const issue of securityIssues) {
209
- const severity = issue.severity;
210
- if (issuesBySeverity[severity] !== undefined) {
211
- issuesBySeverity[severity]++;
212
- }
213
- }
214
-
215
- return {
216
- projectPath,
217
- javaVersion,
218
- buildTool,
219
- dependencies,
220
- securityIssues,
221
- summary: {
222
- totalDependencies: dependencies.length,
223
- issuesBySeverity,
224
- },
225
- };
226
- }
227
-
228
- /**
229
- * Detect build tool
230
- */
231
- private detectBuildTool(projectPath: string): "maven" | "gradle" | "unknown" {
232
- if (existsSync(join(projectPath, "pom.xml"))) {
233
- return "maven";
234
- }
235
- if (
236
- existsSync(join(projectPath, "build.gradle")) ||
237
- existsSync(join(projectPath, "build.gradle.kts"))
238
- ) {
239
- return "gradle";
240
- }
241
- return "unknown";
242
- }
243
-
244
- /**
245
- * Extract dependencies
246
- */
247
- private async extractDependencies(
248
- projectPath: string,
249
- buildTool: string,
250
- ): Promise<JavaDependency[]> {
251
- if (buildTool === "maven") {
252
- return this.parseMavenPom(projectPath);
253
- }
254
- if (buildTool === "gradle") {
255
- return this.parseGradleBuild(projectPath);
256
- }
257
- return [];
258
- }
259
-
260
- /**
261
- * Parse Maven pom.xml
262
- */
263
- private parseMavenPom(projectPath: string): JavaDependency[] {
264
- const dependencies: JavaDependency[] = [];
265
- const pomPath = join(projectPath, "pom.xml");
266
-
267
- if (!existsSync(pomPath)) {
268
- return dependencies;
269
- }
270
-
271
- try {
272
- const content = readFileSync(pomPath, "utf-8");
273
-
274
- // Simple regex parsing for dependencies
275
- const depRegex =
276
- /<dependency>\s*<groupId>([^<]+)<\/groupId>\s*<artifactId>([^<]+)<\/artifactId>\s*(?:<version>([^<]+)<\/version>)?/g;
277
-
278
- let match;
279
- while ((match = depRegex.exec(content)) !== null) {
280
- dependencies.push({
281
- groupId: match[1] || "",
282
- artifactId: match[2] || "",
283
- version: match[3] || "managed",
284
- source: "maven",
285
- });
286
- }
287
- } catch {
288
- // Skip if can't parse
289
- }
290
-
291
- return dependencies;
292
- }
293
-
294
- /**
295
- * Parse Gradle build file
296
- */
297
- private parseGradleBuild(projectPath: string): JavaDependency[] {
298
- const dependencies: JavaDependency[] = [];
299
- const gradlePath = join(projectPath, "build.gradle");
300
- const gradleKtsPath = join(projectPath, "build.gradle.kts");
301
-
302
- const buildFile = existsSync(gradlePath)
303
- ? gradlePath
304
- : existsSync(gradleKtsPath)
305
- ? gradleKtsPath
306
- : null;
307
-
308
- if (!buildFile) {
309
- return dependencies;
310
- }
311
-
312
- try {
313
- const content = readFileSync(buildFile, "utf-8");
314
-
315
- // Match implementation 'group:artifact:version' or implementation("group:artifact:version")
316
- const depRegex =
317
- /(?:implementation|compile|api|testImplementation)\s*[("']([^:]+):([^:]+):([^)"']+)/g;
318
-
319
- let match;
320
- while ((match = depRegex.exec(content)) !== null) {
321
- dependencies.push({
322
- groupId: match[1] || "",
323
- artifactId: match[2] || "",
324
- version: match[3] || "latest",
325
- source: "gradle",
326
- });
327
- }
328
- } catch {
329
- // Skip if can't parse
330
- }
331
-
332
- return dependencies;
333
- }
334
-
335
- /**
336
- * Find all Java files
337
- */
338
- private findJavaFiles(projectPath: string): string[] {
339
- const files: string[] = [];
340
-
341
- const walkDir = (dir: string) => {
342
- try {
343
- const entries = readdirSync(dir);
344
-
345
- for (const entry of entries) {
346
- const fullPath = join(dir, entry);
347
-
348
- // Skip common non-source directories
349
- if (
350
- [
351
- "node_modules",
352
- ".git",
353
- "target",
354
- "build",
355
- ".gradle",
356
- ".idea",
357
- ].includes(entry)
358
- ) {
359
- continue;
360
- }
361
-
362
- try {
363
- const stat = statSync(fullPath);
364
- if (stat.isDirectory()) {
365
- walkDir(fullPath);
366
- } else if (entry.endsWith(".java")) {
367
- files.push(fullPath);
368
- }
369
- } catch {
370
- // Skip files we can't access
371
- }
372
- }
373
- } catch {
374
- // Skip directories we can't access
375
- }
376
- };
377
-
378
- walkDir(projectPath);
379
- return files;
380
- }
381
-
382
- /**
383
- * Scan a Java file for security issues
384
- */
385
- private scanFile(filePath: string): JavaSecurityIssue[] {
386
- const issues: JavaSecurityIssue[] = [];
387
-
388
- try {
389
- const content = readFileSync(filePath, "utf-8");
390
- const lines = content.split("\n");
391
-
392
- // Check for dangerous imports
393
- for (let i = 0; i < lines.length; i++) {
394
- const line = lines[i];
395
- if (!line) continue;
396
-
397
- for (const dangerous of DANGEROUS_IMPORTS) {
398
- if (
399
- line.includes(`import ${dangerous.pkg}`) ||
400
- line.includes(dangerous.pkg)
401
- ) {
402
- issues.push({
403
- type: "dangerous_import",
404
- severity: dangerous.severity,
405
- file: filePath,
406
- line: i + 1,
407
- message: `Dangerous import: ${dangerous.pkg} - ${dangerous.reason}`,
408
- recommendation: `Review usage of ${dangerous.pkg}`,
409
- cwe: dangerous.cwe,
410
- });
411
- }
412
- }
413
- }
414
-
415
- // Check for secrets
416
- for (const secretPattern of JAVA_SECRET_PATTERNS) {
417
- const matches = content.matchAll(secretPattern.pattern);
418
- for (const match of matches) {
419
- const lineNum = content.substring(0, match.index).split("\n").length;
420
- issues.push({
421
- type: "secret",
422
- severity: "critical",
423
- file: filePath,
424
- line: lineNum,
425
- message: `Potential ${secretPattern.type} detected`,
426
- recommendation:
427
- "Move secrets to environment variables or secure vault",
428
- });
429
- }
430
- }
431
-
432
- // Check for vulnerability patterns
433
- for (const vulnPattern of VULNERABILITY_PATTERNS) {
434
- const matches = content.matchAll(vulnPattern.pattern);
435
- for (const match of matches) {
436
- const lineNum = content.substring(0, match.index).split("\n").length;
437
- issues.push({
438
- type: "code_pattern",
439
- severity: vulnPattern.severity,
440
- file: filePath,
441
- line: lineNum,
442
- message: `${vulnPattern.type}: ${vulnPattern.message}`,
443
- recommendation: `Fix the ${vulnPattern.type.toLowerCase()} vulnerability`,
444
- cwe: vulnPattern.cwe,
445
- });
446
- }
447
- }
448
- } catch {
449
- // Skip files we can't read
450
- }
451
-
452
- return issues;
453
- }
454
-
455
- /**
456
- * Detect Java version
457
- */
458
- private detectJavaVersion(projectPath: string): string | undefined {
459
- // Check pom.xml for java version
460
- const pomPath = join(projectPath, "pom.xml");
461
- if (existsSync(pomPath)) {
462
- try {
463
- const content = readFileSync(pomPath, "utf-8");
464
- const match = content.match(/<java\.version>([^<]+)<\/java\.version>/);
465
- if (match && match[1]) {
466
- return match[1];
467
- }
468
- const sourceMatch = content.match(
469
- /<maven\.compiler\.source>([^<]+)<\/maven\.compiler\.source>/,
470
- );
471
- if (sourceMatch && sourceMatch[1]) {
472
- return sourceMatch[1];
473
- }
474
- } catch {
475
- // Skip
476
- }
477
- }
478
-
479
- // Check .java-version file
480
- const javaVersionPath = join(projectPath, ".java-version");
481
- if (existsSync(javaVersionPath)) {
482
- return readFileSync(javaVersionPath, "utf-8").trim();
483
- }
484
-
485
- return undefined;
486
- }
487
- }
488
-
489
- // Export singleton
490
- export const javaAnalyzer = new JavaAnalyzer();