git-repo-analyzer-test 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/.github/copilot-instructions.md +108 -0
- package/.idea/aianalyzer.iml +9 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/API_REFERENCE.md +244 -0
- package/ENHANCEMENTS.md +282 -0
- package/README.md +179 -0
- package/USAGE.md +189 -0
- package/analysis.txt +0 -0
- package/bin/cli.js +135 -0
- package/docs/SONARCLOUD_ANALYSIS_COVERED.md +144 -0
- package/docs/SonarCloud_Presentation_Points.md +81 -0
- package/docs/UI_IMPROVEMENTS.md +117 -0
- package/package-lock_cmd.json +542 -0
- package/package.json +44 -0
- package/package_command.json +16 -0
- package/public/analysis-options.json +31 -0
- package/public/images/README.txt +2 -0
- package/public/images/rws-logo.png +0 -0
- package/public/index.html +2433 -0
- package/repositories.example.txt +17 -0
- package/sample-repos.txt +20 -0
- package/src/analyzers/accessibility.js +47 -0
- package/src/analyzers/cicd-enhanced.js +113 -0
- package/src/analyzers/codeReview-enhanced.js +599 -0
- package/src/analyzers/codeReview-enhanced.js:Zone.Identifier +3 -0
- package/src/analyzers/codeReview.js +171 -0
- package/src/analyzers/codeReview.js:Zone.Identifier +3 -0
- package/src/analyzers/documentation-enhanced.js +137 -0
- package/src/analyzers/performance-enhanced.js +747 -0
- package/src/analyzers/performance-enhanced.js:Zone.Identifier +3 -0
- package/src/analyzers/performance.js +211 -0
- package/src/analyzers/performance.js:Zone.Identifier +3 -0
- package/src/analyzers/performance_cmd.js +216 -0
- package/src/analyzers/quality-enhanced.js +386 -0
- package/src/analyzers/quality-enhanced.js:Zone.Identifier +3 -0
- package/src/analyzers/quality.js +92 -0
- package/src/analyzers/quality.js:Zone.Identifier +3 -0
- package/src/analyzers/security-enhanced.js +512 -0
- package/src/analyzers/security-enhanced.js:Zone.Identifier +3 -0
- package/src/analyzers/snyk-ai.js:Zone.Identifier +3 -0
- package/src/analyzers/sonarcloud.js +928 -0
- package/src/analyzers/vulnerability.js +185 -0
- package/src/analyzers/vulnerability.js:Zone.Identifier +3 -0
- package/src/cli.js:Zone.Identifier +3 -0
- package/src/config.js +43 -0
- package/src/core/analyzerEngine.js +68 -0
- package/src/core/reportGenerator.js +21 -0
- package/src/gemini.js +321 -0
- package/src/github/client.js +124 -0
- package/src/github/client.js:Zone.Identifier +3 -0
- package/src/index.js +93 -0
- package/src/index_cmd.js +130 -0
- package/src/openai.js +297 -0
- package/src/report/generator.js +459 -0
- package/src/report/generator_cmd.js +459 -0
- package/src/report/pdf-generator.js +387 -0
- package/src/report/pdf-generator.js:Zone.Identifier +3 -0
- package/src/server.js +431 -0
- package/src/server.js:Zone.Identifier +3 -0
- package/src/server_cmd.js +434 -0
- package/src/sonarcloud/client.js +365 -0
- package/src/sonarcloud/scanner.js +171 -0
- package/src.zip +0 -0
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Security & Vulnerability Analyzer
|
|
3
|
+
* Checks against OWASP Top 10 vulnerabilities with detailed insights
|
|
4
|
+
*/
|
|
5
|
+
export class SecurityAnalyzer {
|
|
6
|
+
constructor(githubClient) {
|
|
7
|
+
this.client = githubClient;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Comprehensive security analysis
|
|
12
|
+
*/
|
|
13
|
+
async analyzeSecurityVulnerabilities(owner, repo) {
|
|
14
|
+
try {
|
|
15
|
+
const repoData = await this.client.getRepository(owner, repo);
|
|
16
|
+
|
|
17
|
+
const owasp10Issues = this.scanOWASPTop10(repoData);
|
|
18
|
+
const securityFeatures = this.checkSecurityFeatures(repoData);
|
|
19
|
+
const score = this.calculateSecurityScore(owasp10Issues, securityFeatures);
|
|
20
|
+
const rating = this.getRating(score);
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
score,
|
|
24
|
+
rating,
|
|
25
|
+
riskLevel: this.determineRiskLevel(score),
|
|
26
|
+
owasp10Vulnerabilities: owasp10Issues,
|
|
27
|
+
securityFeatures,
|
|
28
|
+
recommendations: this.generateSecurityRecommendations(
|
|
29
|
+
owasp10Issues,
|
|
30
|
+
securityFeatures
|
|
31
|
+
),
|
|
32
|
+
riskFactors: this.identifyRiskFactors(repoData, owasp10Issues),
|
|
33
|
+
bestPractices: this.checkSecurityBestPractices(repoData),
|
|
34
|
+
details: {
|
|
35
|
+
dependencySecurity: this.assessDependencySecurity(repoData),
|
|
36
|
+
codeExposure: this.assessCodeExposure(repoData),
|
|
37
|
+
accessControl: this.assessAccessControl(repoData),
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
} catch (error) {
|
|
41
|
+
throw new Error(`Security analysis failed: ${error.message}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Scan for OWASP Top 10 vulnerabilities
|
|
47
|
+
*/
|
|
48
|
+
scanOWASPTop10(repoData) {
|
|
49
|
+
const vulnerabilities = [];
|
|
50
|
+
|
|
51
|
+
// A01:2021 - Broken Access Control
|
|
52
|
+
if (!repoData.private && repoData.open_issues_count > 50) {
|
|
53
|
+
vulnerabilities.push({
|
|
54
|
+
rank: 'A01',
|
|
55
|
+
title: 'Broken Access Control',
|
|
56
|
+
severity: 'HIGH',
|
|
57
|
+
description: 'Potential access control vulnerabilities detected',
|
|
58
|
+
location: 'Repository access settings',
|
|
59
|
+
indicators: ['Public repository with high issue count'],
|
|
60
|
+
remediation: [
|
|
61
|
+
'Implement proper RBAC (Role-Based Access Control)',
|
|
62
|
+
'Audit repository permissions',
|
|
63
|
+
'Use branch protection rules',
|
|
64
|
+
'Implement code review requirements',
|
|
65
|
+
],
|
|
66
|
+
score: 7,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// A02:2021 - Cryptographic Failures
|
|
71
|
+
if (!repoData.security_and_analysis?.secret_scanning?.status) {
|
|
72
|
+
vulnerabilities.push({
|
|
73
|
+
rank: 'A02',
|
|
74
|
+
title: 'Cryptographic Failures',
|
|
75
|
+
severity: 'CRITICAL',
|
|
76
|
+
description: 'No secret scanning enabled - potential credential exposure',
|
|
77
|
+
location: 'Secret scanning configuration',
|
|
78
|
+
indicators: ['Secret scanning disabled', 'No credential protection'],
|
|
79
|
+
remediation: [
|
|
80
|
+
'Enable secret scanning on GitHub',
|
|
81
|
+
'Rotate any exposed credentials',
|
|
82
|
+
'Use GitHub secrets management',
|
|
83
|
+
'Implement pre-commit hooks to prevent secret commits',
|
|
84
|
+
'Use environment-based configuration',
|
|
85
|
+
],
|
|
86
|
+
score: 9,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// A03:2021 - Injection
|
|
91
|
+
const isSuspiciousOfInjection = repoData.language === 'PHP' ||
|
|
92
|
+
repoData.language === 'JavaScript' ||
|
|
93
|
+
repoData.language === 'Python';
|
|
94
|
+
if (isSuspiciousOfInjection && repoData.open_issues_count > 20) {
|
|
95
|
+
vulnerabilities.push({
|
|
96
|
+
rank: 'A03',
|
|
97
|
+
title: 'Injection',
|
|
98
|
+
severity: 'HIGH',
|
|
99
|
+
description: 'Potential injection vulnerabilities (SQL, NoSQL, OS command)',
|
|
100
|
+
location: 'Input validation and database queries',
|
|
101
|
+
indicators: [
|
|
102
|
+
'Dynamic query construction',
|
|
103
|
+
'Unsanitized user input',
|
|
104
|
+
'High issue count suggesting potential bugs',
|
|
105
|
+
],
|
|
106
|
+
remediation: [
|
|
107
|
+
'Use parameterized queries / prepared statements',
|
|
108
|
+
'Implement input validation and sanitization',
|
|
109
|
+
'Use ORM frameworks when possible',
|
|
110
|
+
'Apply security scanning tools',
|
|
111
|
+
'Code review all database interactions',
|
|
112
|
+
],
|
|
113
|
+
score: 8,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// A04:2021 - Insecure Design
|
|
118
|
+
if (!repoData.has_pages && !repoData.description) {
|
|
119
|
+
vulnerabilities.push({
|
|
120
|
+
rank: 'A04',
|
|
121
|
+
title: 'Insecure Design',
|
|
122
|
+
severity: 'MEDIUM',
|
|
123
|
+
description: 'Lack of security architecture documentation',
|
|
124
|
+
location: 'Documentation and design specifications',
|
|
125
|
+
indicators: [
|
|
126
|
+
'No documented security requirements',
|
|
127
|
+
'Missing threat modeling',
|
|
128
|
+
'No design documentation',
|
|
129
|
+
],
|
|
130
|
+
remediation: [
|
|
131
|
+
'Document security requirements',
|
|
132
|
+
'Perform threat modeling',
|
|
133
|
+
'Implement security by design',
|
|
134
|
+
'Create architecture documentation',
|
|
135
|
+
'Define security acceptance criteria',
|
|
136
|
+
],
|
|
137
|
+
score: 6,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// A05:2021 - Security Misconfiguration
|
|
142
|
+
if (!repoData.security_and_analysis?.dependabot_security_updates?.status) {
|
|
143
|
+
vulnerabilities.push({
|
|
144
|
+
rank: 'A05',
|
|
145
|
+
title: 'Security Misconfiguration',
|
|
146
|
+
severity: 'HIGH',
|
|
147
|
+
description: 'Security features not properly configured',
|
|
148
|
+
location: 'Repository settings and CI/CD configuration',
|
|
149
|
+
indicators: [
|
|
150
|
+
'Dependabot security updates disabled',
|
|
151
|
+
'No dependency vulnerability scanning',
|
|
152
|
+
'Default security configurations',
|
|
153
|
+
],
|
|
154
|
+
remediation: [
|
|
155
|
+
'Enable Dependabot security updates',
|
|
156
|
+
'Configure security scanning in CI/CD',
|
|
157
|
+
'Implement secrets management',
|
|
158
|
+
'Use security headers',
|
|
159
|
+
'Regular security configuration audit',
|
|
160
|
+
],
|
|
161
|
+
score: 7,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// A06:2021 - Vulnerable and Outdated Components
|
|
166
|
+
const daysSinceUpdate = Math.floor(
|
|
167
|
+
(new Date() - new Date(repoData.updated_at)) / (1000 * 60 * 60 * 24)
|
|
168
|
+
);
|
|
169
|
+
if (daysSinceUpdate > 90) {
|
|
170
|
+
vulnerabilities.push({
|
|
171
|
+
rank: 'A06',
|
|
172
|
+
title: 'Vulnerable and Outdated Components',
|
|
173
|
+
severity: 'HIGH',
|
|
174
|
+
description: `Repository not updated for ${daysSinceUpdate} days`,
|
|
175
|
+
location: 'Dependencies and libraries',
|
|
176
|
+
indicators: [
|
|
177
|
+
'Stale dependencies',
|
|
178
|
+
'Outdated framework versions',
|
|
179
|
+
'Known security vulnerabilities in components',
|
|
180
|
+
],
|
|
181
|
+
remediation: [
|
|
182
|
+
'Update all dependencies regularly',
|
|
183
|
+
'Use dependency management tools',
|
|
184
|
+
'Monitor security advisories',
|
|
185
|
+
'Set up automated dependency updates',
|
|
186
|
+
'Regular security patches',
|
|
187
|
+
],
|
|
188
|
+
score: 8,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// A07:2021 - Authentication & Session Management (Potential)
|
|
193
|
+
if (repoData.language === 'JavaScript' || repoData.language === 'PHP') {
|
|
194
|
+
vulnerabilities.push({
|
|
195
|
+
rank: 'A07',
|
|
196
|
+
title: 'Authentication & Session Management',
|
|
197
|
+
severity: 'MEDIUM',
|
|
198
|
+
description: 'Potential authentication vulnerabilities in web application',
|
|
199
|
+
location: 'Authentication and session handling code',
|
|
200
|
+
indicators: ['Web framework detected', 'User authentication likely'],
|
|
201
|
+
remediation: [
|
|
202
|
+
'Implement strong password policies',
|
|
203
|
+
'Use multi-factor authentication',
|
|
204
|
+
'Secure session management',
|
|
205
|
+
'Implement proper token expiration',
|
|
206
|
+
'Use HTTPS only',
|
|
207
|
+
'Implement CSRF protection',
|
|
208
|
+
],
|
|
209
|
+
score: 6,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// A08:2021 - Software and Data Integrity Failures
|
|
214
|
+
if (!repoData.license) {
|
|
215
|
+
vulnerabilities.push({
|
|
216
|
+
rank: 'A08',
|
|
217
|
+
title: 'Software and Data Integrity Failures',
|
|
218
|
+
severity: 'MEDIUM',
|
|
219
|
+
description: 'No defined integrity verification mechanism',
|
|
220
|
+
location: 'Code integrity and license verification',
|
|
221
|
+
indicators: ['No license defined', 'No code signing', 'No integrity checks'],
|
|
222
|
+
remediation: [
|
|
223
|
+
'Add LICENSE file',
|
|
224
|
+
'Implement code signing',
|
|
225
|
+
'Use cryptographic verification',
|
|
226
|
+
'Secure dependency sources',
|
|
227
|
+
'Implement integrity checks',
|
|
228
|
+
],
|
|
229
|
+
score: 5,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// A09:2021 - Logging & Monitoring Failures
|
|
234
|
+
vulnerabilities.push({
|
|
235
|
+
rank: 'A09',
|
|
236
|
+
title: 'Logging and Monitoring Failures',
|
|
237
|
+
severity: 'MEDIUM',
|
|
238
|
+
description: 'No evidence of comprehensive logging/monitoring setup',
|
|
239
|
+
location: 'Application instrumentation',
|
|
240
|
+
indicators: ['No documented logging strategy', 'No monitoring topics'],
|
|
241
|
+
remediation: [
|
|
242
|
+
'Implement comprehensive logging',
|
|
243
|
+
'Log all security events',
|
|
244
|
+
'Monitor for suspicious activity',
|
|
245
|
+
'Set up alerts for anomalies',
|
|
246
|
+
'Retain logs securely',
|
|
247
|
+
],
|
|
248
|
+
score: 5,
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// A10:2021 - Server-Side Request Forgery (SSRF)
|
|
252
|
+
if (repoData.language === 'Python' || repoData.language === 'JavaScript') {
|
|
253
|
+
vulnerabilities.push({
|
|
254
|
+
rank: 'A10',
|
|
255
|
+
title: 'Server-Side Request Forgery (SSRF)',
|
|
256
|
+
severity: 'MEDIUM',
|
|
257
|
+
description: 'Potential SSRF vulnerabilities from external requests',
|
|
258
|
+
location: 'External API calls and HTTP requests',
|
|
259
|
+
indicators: ['Makes external HTTP requests', 'Network I/O detected'],
|
|
260
|
+
remediation: [
|
|
261
|
+
'Validate and sanitize URLs',
|
|
262
|
+
'Implement URL whitelist',
|
|
263
|
+
'Disable unused URL schemes',
|
|
264
|
+
'Use network segmentation',
|
|
265
|
+
'Implement timeout controls',
|
|
266
|
+
],
|
|
267
|
+
score: 5,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return vulnerabilities;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Check security features enabled
|
|
276
|
+
*/
|
|
277
|
+
checkSecurityFeatures(repoData) {
|
|
278
|
+
return {
|
|
279
|
+
secretScanning: {
|
|
280
|
+
enabled: repoData.security_and_analysis?.secret_scanning?.status === 'enabled',
|
|
281
|
+
description: 'Detects and prevents exposed secrets',
|
|
282
|
+
},
|
|
283
|
+
dependabotSecurityUpdates: {
|
|
284
|
+
enabled: repoData.security_and_analysis?.dependabot_security_updates?.status === 'enabled',
|
|
285
|
+
description: 'Automatically updates vulnerable dependencies',
|
|
286
|
+
},
|
|
287
|
+
branchProtection: {
|
|
288
|
+
status: 'Unknown - requires additional API call',
|
|
289
|
+
description: 'Enforces code review before merging',
|
|
290
|
+
},
|
|
291
|
+
codeQL: {
|
|
292
|
+
status: 'Unknown - requires additional API call',
|
|
293
|
+
description: 'Advanced security code scanning',
|
|
294
|
+
},
|
|
295
|
+
isPrivate: {
|
|
296
|
+
enabled: repoData.private,
|
|
297
|
+
description: 'Repository access is restricted',
|
|
298
|
+
},
|
|
299
|
+
hasLicense: {
|
|
300
|
+
enabled: !!repoData.license,
|
|
301
|
+
description: 'Legal terms defined for usage',
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Assess dependency security
|
|
308
|
+
*/
|
|
309
|
+
assessDependencySecurity(repoData) {
|
|
310
|
+
return {
|
|
311
|
+
hasPackageJson: repoData.language === 'JavaScript' || repoData.language === 'TypeScript',
|
|
312
|
+
hasPyproject: repoData.language === 'Python',
|
|
313
|
+
hasGemfile: repoData.language === 'Ruby',
|
|
314
|
+
status: 'Use npm audit, pip-audit, or bundle audit',
|
|
315
|
+
recommendations: [
|
|
316
|
+
'Regularly audit dependencies for vulnerabilities',
|
|
317
|
+
'Keep dependencies up to date',
|
|
318
|
+
'Use lock files (package-lock.json, Pipfile.lock)',
|
|
319
|
+
'Set up automated dependency updates',
|
|
320
|
+
],
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Assess code exposure risks
|
|
326
|
+
*/
|
|
327
|
+
assessCodeExposure(repoData) {
|
|
328
|
+
return {
|
|
329
|
+
isPublic: !repoData.private,
|
|
330
|
+
hasSensitiveTopics: repoData.topics?.some(
|
|
331
|
+
(t) => ['secret', 'password', 'key', 'credential'].includes(t)
|
|
332
|
+
),
|
|
333
|
+
recommendations: [
|
|
334
|
+
'Use .gitignore to exclude sensitive files',
|
|
335
|
+
'Never commit credentials or API keys',
|
|
336
|
+
'Use environment variables for configuration',
|
|
337
|
+
'Rotate any exposed credentials immediately',
|
|
338
|
+
'Use GitHub secrets for CI/CD',
|
|
339
|
+
],
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Assess access control
|
|
345
|
+
*/
|
|
346
|
+
assessAccessControl(repoData) {
|
|
347
|
+
return {
|
|
348
|
+
isPrivate: repoData.private,
|
|
349
|
+
pushToBranchDisabled: repoData.topics?.includes('branch-protection'),
|
|
350
|
+
recommendations: [
|
|
351
|
+
'Require pull requests for all changes',
|
|
352
|
+
'Require status checks to pass',
|
|
353
|
+
'Require code reviews',
|
|
354
|
+
'Enforce branch naming conventions',
|
|
355
|
+
'Limit who can push to main/master',
|
|
356
|
+
],
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Calculate security score
|
|
362
|
+
*/
|
|
363
|
+
calculateSecurityScore(vulnerabilities, securityFeatures) {
|
|
364
|
+
let score = 100;
|
|
365
|
+
|
|
366
|
+
// Deduct for vulnerabilities
|
|
367
|
+
vulnerabilities.forEach((vuln) => {
|
|
368
|
+
score -= vuln.score;
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// Add points for security features enabled
|
|
372
|
+
if (securityFeatures.secretScanning.enabled) score += 10;
|
|
373
|
+
if (securityFeatures.dependabotSecurityUpdates.enabled) score += 8;
|
|
374
|
+
if (securityFeatures.isPrivate.enabled) score += 5;
|
|
375
|
+
if (securityFeatures.hasLicense.enabled) score += 3;
|
|
376
|
+
|
|
377
|
+
return Math.max(0, Math.min(100, score));
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Identify risk factors
|
|
382
|
+
*/
|
|
383
|
+
identifyRiskFactors(repoData, owasp10Issues) {
|
|
384
|
+
const factors = [];
|
|
385
|
+
|
|
386
|
+
if (repoData.archived) {
|
|
387
|
+
factors.push('Repository is archived and not maintained');
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (!repoData.private) {
|
|
391
|
+
factors.push('Public repository - code is visible to all');
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (!repoData.security_and_analysis?.secret_scanning?.status) {
|
|
395
|
+
factors.push('Secret scanning is disabled');
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (!repoData.security_and_analysis?.dependabot_security_updates?.status) {
|
|
399
|
+
factors.push('Dependabot security updates are disabled');
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const daysSinceUpdate = Math.floor(
|
|
403
|
+
(new Date() - new Date(repoData.updated_at)) / (1000 * 60 * 60 * 24)
|
|
404
|
+
);
|
|
405
|
+
if (daysSinceUpdate > 365) {
|
|
406
|
+
factors.push(`Repository not updated for ${daysSinceUpdate} days`);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (repoData.open_issues_count > 100) {
|
|
410
|
+
factors.push(`High number of open issues: ${repoData.open_issues_count}`);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
factors.push(`Found ${owasp10Issues.length} potential OWASP Top 10 vulnerabilities`);
|
|
414
|
+
|
|
415
|
+
return factors;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Check security best practices
|
|
420
|
+
*/
|
|
421
|
+
checkSecurityBestPractices(repoData) {
|
|
422
|
+
return {
|
|
423
|
+
hasSecurity: repoData.topics?.includes('security'),
|
|
424
|
+
hasSecurityPolicy: repoData.topics?.includes('security-policy'),
|
|
425
|
+
hasSecurityAudit: repoData.topics?.includes('security-audit'),
|
|
426
|
+
hasCodeOfConduct: repoData.topics?.includes('code-of-conduct'),
|
|
427
|
+
recommendations: [
|
|
428
|
+
'Create SECURITY.md with security policy',
|
|
429
|
+
'Implement security.txt for vulnerability reporting',
|
|
430
|
+
'Add code of conduct for community',
|
|
431
|
+
'Perform regular security audits',
|
|
432
|
+
'Keep security documentation updated',
|
|
433
|
+
],
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Generate security recommendations
|
|
439
|
+
*/
|
|
440
|
+
generateSecurityRecommendations(vulnerabilities, securityFeatures) {
|
|
441
|
+
const recommendations = [];
|
|
442
|
+
|
|
443
|
+
// Prioritize critical vulnerabilities
|
|
444
|
+
vulnerabilities
|
|
445
|
+
.filter((v) => v.severity === 'CRITICAL')
|
|
446
|
+
.forEach((v) => {
|
|
447
|
+
recommendations.push({
|
|
448
|
+
priority: 'CRITICAL',
|
|
449
|
+
issue: v.title,
|
|
450
|
+
actions: v.remediation,
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
// Add high severity issues
|
|
455
|
+
vulnerabilities
|
|
456
|
+
.filter((v) => v.severity === 'HIGH')
|
|
457
|
+
.forEach((v) => {
|
|
458
|
+
recommendations.push({
|
|
459
|
+
priority: 'HIGH',
|
|
460
|
+
issue: v.title,
|
|
461
|
+
actions: v.remediation,
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
// Add feature recommendations
|
|
466
|
+
if (!securityFeatures.secretScanning.enabled) {
|
|
467
|
+
recommendations.push({
|
|
468
|
+
priority: 'HIGH',
|
|
469
|
+
issue: 'Enable Secret Scanning',
|
|
470
|
+
actions: ['Go to Settings > Code security and analysis', 'Enable Secret Scanning'],
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
if (!securityFeatures.dependabotSecurityUpdates.enabled) {
|
|
475
|
+
recommendations.push({
|
|
476
|
+
priority: 'HIGH',
|
|
477
|
+
issue: 'Enable Dependabot Security Updates',
|
|
478
|
+
actions: [
|
|
479
|
+
'Go to Settings > Code security and analysis',
|
|
480
|
+
'Enable Dependabot security updates',
|
|
481
|
+
],
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return recommendations;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Determine overall risk level
|
|
490
|
+
*/
|
|
491
|
+
determineRiskLevel(score) {
|
|
492
|
+
if (score >= 80) return 'LOW';
|
|
493
|
+
if (score >= 60) return 'MEDIUM';
|
|
494
|
+
if (score >= 40) return 'HIGH';
|
|
495
|
+
return 'CRITICAL';
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Get rating from score
|
|
500
|
+
*/
|
|
501
|
+
getRating(score) {
|
|
502
|
+
if (score >= 90) return 'A+';
|
|
503
|
+
if (score >= 80) return 'A';
|
|
504
|
+
if (score >= 70) return 'B+';
|
|
505
|
+
if (score >= 60) return 'B';
|
|
506
|
+
if (score >= 50) return 'C+';
|
|
507
|
+
if (score >= 40) return 'C';
|
|
508
|
+
return 'F';
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
export default SecurityAnalyzer;
|