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