@nahisaho/musubix-security 1.8.0 → 1.8.5

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 (186) hide show
  1. package/README.md +27 -0
  2. package/dist/analyzers/ai/index.d.ts +6 -0
  3. package/dist/analyzers/ai/index.d.ts.map +1 -0
  4. package/dist/analyzers/ai/index.js +6 -0
  5. package/dist/analyzers/ai/index.js.map +1 -0
  6. package/dist/analyzers/ai/prompt-injection-detector.d.ts +152 -0
  7. package/dist/analyzers/ai/prompt-injection-detector.d.ts.map +1 -0
  8. package/dist/analyzers/ai/prompt-injection-detector.js +468 -0
  9. package/dist/analyzers/ai/prompt-injection-detector.js.map +1 -0
  10. package/dist/analyzers/api/api-security-analyzer.d.ts +263 -0
  11. package/dist/analyzers/api/api-security-analyzer.d.ts.map +1 -0
  12. package/dist/analyzers/api/api-security-analyzer.js +581 -0
  13. package/dist/analyzers/api/api-security-analyzer.js.map +1 -0
  14. package/dist/analyzers/compliance/compliance-checker.d.ts +201 -0
  15. package/dist/analyzers/compliance/compliance-checker.d.ts.map +1 -0
  16. package/dist/analyzers/compliance/compliance-checker.js +772 -0
  17. package/dist/analyzers/compliance/compliance-checker.js.map +1 -0
  18. package/dist/analyzers/container/image-scanner.d.ts +163 -0
  19. package/dist/analyzers/container/image-scanner.d.ts.map +1 -0
  20. package/dist/analyzers/container/image-scanner.js +459 -0
  21. package/dist/analyzers/container/image-scanner.js.map +1 -0
  22. package/dist/analyzers/container/index.d.ts +6 -0
  23. package/dist/analyzers/container/index.d.ts.map +1 -0
  24. package/dist/analyzers/container/index.js +6 -0
  25. package/dist/analyzers/container/index.js.map +1 -0
  26. package/dist/analyzers/dashboard/security-dashboard.d.ts +286 -0
  27. package/dist/analyzers/dashboard/security-dashboard.d.ts.map +1 -0
  28. package/dist/analyzers/dashboard/security-dashboard.js +796 -0
  29. package/dist/analyzers/dashboard/security-dashboard.js.map +1 -0
  30. package/dist/analyzers/iac/iac-checker.d.ts +124 -0
  31. package/dist/analyzers/iac/iac-checker.d.ts.map +1 -0
  32. package/dist/analyzers/iac/iac-checker.js +755 -0
  33. package/dist/analyzers/iac/iac-checker.js.map +1 -0
  34. package/dist/analyzers/iac/index.d.ts +6 -0
  35. package/dist/analyzers/iac/index.d.ts.map +1 -0
  36. package/dist/analyzers/iac/index.js +6 -0
  37. package/dist/analyzers/iac/index.js.map +1 -0
  38. package/dist/analyzers/index.d.ts +9 -0
  39. package/dist/analyzers/index.d.ts.map +1 -0
  40. package/dist/analyzers/index.js +13 -0
  41. package/dist/analyzers/index.js.map +1 -0
  42. package/dist/analyzers/monitor/realtime-monitor.d.ts +216 -0
  43. package/dist/analyzers/monitor/realtime-monitor.d.ts.map +1 -0
  44. package/dist/analyzers/monitor/realtime-monitor.js +601 -0
  45. package/dist/analyzers/monitor/realtime-monitor.js.map +1 -0
  46. package/dist/analyzers/sast/index.d.ts +7 -0
  47. package/dist/analyzers/sast/index.d.ts.map +1 -0
  48. package/dist/analyzers/sast/index.js +7 -0
  49. package/dist/analyzers/sast/index.js.map +1 -0
  50. package/dist/analyzers/sast/interprocedural-analyzer.d.ts +276 -0
  51. package/dist/analyzers/sast/interprocedural-analyzer.d.ts.map +1 -0
  52. package/dist/analyzers/sast/interprocedural-analyzer.js +635 -0
  53. package/dist/analyzers/sast/interprocedural-analyzer.js.map +1 -0
  54. package/dist/analyzers/sast/zero-day-detector.d.ts +183 -0
  55. package/dist/analyzers/sast/zero-day-detector.d.ts.map +1 -0
  56. package/dist/analyzers/sast/zero-day-detector.js +593 -0
  57. package/dist/analyzers/sast/zero-day-detector.js.map +1 -0
  58. package/dist/analyzers/sca/dependency-scanner.d.ts +275 -0
  59. package/dist/analyzers/sca/dependency-scanner.d.ts.map +1 -0
  60. package/dist/analyzers/sca/dependency-scanner.js +642 -0
  61. package/dist/analyzers/sca/dependency-scanner.js.map +1 -0
  62. package/dist/core/index.d.ts +8 -0
  63. package/dist/core/index.d.ts.map +1 -0
  64. package/dist/core/index.js +10 -0
  65. package/dist/core/index.js.map +1 -0
  66. package/dist/core/pipeline-manager.d.ts +105 -0
  67. package/dist/core/pipeline-manager.d.ts.map +1 -0
  68. package/dist/core/pipeline-manager.js +449 -0
  69. package/dist/core/pipeline-manager.js.map +1 -0
  70. package/dist/core/result-aggregator.d.ts +96 -0
  71. package/dist/core/result-aggregator.d.ts.map +1 -0
  72. package/dist/core/result-aggregator.js +462 -0
  73. package/dist/core/result-aggregator.js.map +1 -0
  74. package/dist/index.d.ts +15 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +68 -0
  77. package/dist/index.js.map +1 -1
  78. package/dist/integrations/ci-integration.d.ts +227 -0
  79. package/dist/integrations/ci-integration.d.ts.map +1 -0
  80. package/dist/integrations/ci-integration.js +472 -0
  81. package/dist/integrations/ci-integration.js.map +1 -0
  82. package/dist/integrations/git-hooks.d.ts +155 -0
  83. package/dist/integrations/git-hooks.d.ts.map +1 -0
  84. package/dist/integrations/git-hooks.js +425 -0
  85. package/dist/integrations/git-hooks.js.map +1 -0
  86. package/dist/integrations/index.d.ts +9 -0
  87. package/dist/integrations/index.d.ts.map +1 -0
  88. package/dist/integrations/index.js +9 -0
  89. package/dist/integrations/index.js.map +1 -0
  90. package/dist/integrations/report-aggregator.d.ts +250 -0
  91. package/dist/integrations/report-aggregator.d.ts.map +1 -0
  92. package/dist/integrations/report-aggregator.js +488 -0
  93. package/dist/integrations/report-aggregator.js.map +1 -0
  94. package/dist/integrations/vscode-integration.d.ts +245 -0
  95. package/dist/integrations/vscode-integration.d.ts.map +1 -0
  96. package/dist/integrations/vscode-integration.js +449 -0
  97. package/dist/integrations/vscode-integration.js.map +1 -0
  98. package/dist/intelligence/attack-pattern-matcher.d.ts +217 -0
  99. package/dist/intelligence/attack-pattern-matcher.d.ts.map +1 -0
  100. package/dist/intelligence/attack-pattern-matcher.js +887 -0
  101. package/dist/intelligence/attack-pattern-matcher.js.map +1 -0
  102. package/dist/intelligence/index.d.ts +12 -0
  103. package/dist/intelligence/index.d.ts.map +1 -0
  104. package/dist/intelligence/index.js +18 -0
  105. package/dist/intelligence/index.js.map +1 -0
  106. package/dist/intelligence/neuro-symbolic-core.d.ts +88 -0
  107. package/dist/intelligence/neuro-symbolic-core.d.ts.map +1 -0
  108. package/dist/intelligence/neuro-symbolic-core.js +403 -0
  109. package/dist/intelligence/neuro-symbolic-core.js.map +1 -0
  110. package/dist/intelligence/predictive-analyzer.d.ts +317 -0
  111. package/dist/intelligence/predictive-analyzer.d.ts.map +1 -0
  112. package/dist/intelligence/predictive-analyzer.js +714 -0
  113. package/dist/intelligence/predictive-analyzer.js.map +1 -0
  114. package/dist/intelligence/risk-scorer.d.ts +333 -0
  115. package/dist/intelligence/risk-scorer.d.ts.map +1 -0
  116. package/dist/intelligence/risk-scorer.js +824 -0
  117. package/dist/intelligence/risk-scorer.js.map +1 -0
  118. package/dist/intelligence/security-analytics.d.ts +349 -0
  119. package/dist/intelligence/security-analytics.d.ts.map +1 -0
  120. package/dist/intelligence/security-analytics.js +813 -0
  121. package/dist/intelligence/security-analytics.js.map +1 -0
  122. package/dist/intelligence/threat-intelligence.d.ts +288 -0
  123. package/dist/intelligence/threat-intelligence.d.ts.map +1 -0
  124. package/dist/intelligence/threat-intelligence.js +639 -0
  125. package/dist/intelligence/threat-intelligence.js.map +1 -0
  126. package/dist/policy/index.d.ts +6 -0
  127. package/dist/policy/index.d.ts.map +1 -0
  128. package/dist/policy/index.js +6 -0
  129. package/dist/policy/index.js.map +1 -0
  130. package/dist/policy/policy-engine.d.ts +254 -0
  131. package/dist/policy/policy-engine.d.ts.map +1 -0
  132. package/dist/policy/policy-engine.js +651 -0
  133. package/dist/policy/policy-engine.js.map +1 -0
  134. package/dist/remediation/auto-fixer.d.ts +179 -0
  135. package/dist/remediation/auto-fixer.d.ts.map +1 -0
  136. package/dist/remediation/auto-fixer.js +540 -0
  137. package/dist/remediation/auto-fixer.js.map +1 -0
  138. package/dist/remediation/fix-validator.d.ts +195 -0
  139. package/dist/remediation/fix-validator.d.ts.map +1 -0
  140. package/dist/remediation/fix-validator.js +462 -0
  141. package/dist/remediation/fix-validator.js.map +1 -0
  142. package/dist/remediation/index.d.ts +10 -0
  143. package/dist/remediation/index.d.ts.map +1 -0
  144. package/dist/remediation/index.js +15 -0
  145. package/dist/remediation/index.js.map +1 -0
  146. package/dist/remediation/patch-generator.d.ts +203 -0
  147. package/dist/remediation/patch-generator.d.ts.map +1 -0
  148. package/dist/remediation/patch-generator.js +533 -0
  149. package/dist/remediation/patch-generator.js.map +1 -0
  150. package/dist/remediation/remediation-planner.d.ts +262 -0
  151. package/dist/remediation/remediation-planner.d.ts.map +1 -0
  152. package/dist/remediation/remediation-planner.js +531 -0
  153. package/dist/remediation/remediation-planner.js.map +1 -0
  154. package/dist/remediation/secure-code-transformer.d.ts +222 -0
  155. package/dist/remediation/secure-code-transformer.d.ts.map +1 -0
  156. package/dist/remediation/secure-code-transformer.js +625 -0
  157. package/dist/remediation/secure-code-transformer.js.map +1 -0
  158. package/dist/types/fix.d.ts +3 -1
  159. package/dist/types/fix.d.ts.map +1 -1
  160. package/dist/types/index.d.ts +6 -0
  161. package/dist/types/index.d.ts.map +1 -1
  162. package/dist/types/index.js +1 -0
  163. package/dist/types/index.js.map +1 -1
  164. package/dist/types/interprocedural.d.ts +203 -0
  165. package/dist/types/interprocedural.d.ts.map +1 -0
  166. package/dist/types/interprocedural.js +7 -0
  167. package/dist/types/interprocedural.js.map +1 -0
  168. package/dist/types/neuro-symbolic.d.ts +179 -0
  169. package/dist/types/neuro-symbolic.d.ts.map +1 -0
  170. package/dist/types/neuro-symbolic.js +7 -0
  171. package/dist/types/neuro-symbolic.js.map +1 -0
  172. package/dist/types/pipeline.d.ts +173 -0
  173. package/dist/types/pipeline.d.ts.map +1 -0
  174. package/dist/types/pipeline.js +7 -0
  175. package/dist/types/pipeline.js.map +1 -0
  176. package/dist/types/result.d.ts +134 -0
  177. package/dist/types/result.d.ts.map +1 -0
  178. package/dist/types/result.js +25 -0
  179. package/dist/types/result.js.map +1 -0
  180. package/dist/types/vulnerability.d.ts +2 -2
  181. package/dist/types/vulnerability.d.ts.map +1 -1
  182. package/dist/types/zero-day.d.ts +146 -0
  183. package/dist/types/zero-day.d.ts.map +1 -0
  184. package/dist/types/zero-day.js +7 -0
  185. package/dist/types/zero-day.js.map +1 -0
  186. package/package.json +2 -2
@@ -0,0 +1,714 @@
1
+ /**
2
+ * @fileoverview Predictive Security Analyzer
3
+ * @module @nahisaho/musubix-security/intelligence/predictive-analyzer
4
+ *
5
+ * Provides security prediction, anomaly forecasting, risk projection,
6
+ * and proactive security recommendations.
7
+ */
8
+ // ============================================================================
9
+ // PredictiveAnalyzer Class
10
+ // ============================================================================
11
+ /**
12
+ * Predictive Security Analyzer
13
+ */
14
+ export class PredictiveAnalyzer {
15
+ options;
16
+ historicalData = new Map();
17
+ alerts = [];
18
+ anomalies = [];
19
+ constructor(options = {}) {
20
+ this.options = {
21
+ lookbackDays: options.lookbackDays ?? 30,
22
+ forecastDays: options.forecastDays ?? 14,
23
+ anomalySensitivity: options.anomalySensitivity ?? 0.7,
24
+ alertThresholds: options.alertThresholds ?? {
25
+ riskIncrease: 20,
26
+ vulnerabilitySurge: 50,
27
+ deviationPercent: 30,
28
+ },
29
+ enableProactiveAlerts: options.enableProactiveAlerts ?? true,
30
+ };
31
+ }
32
+ /**
33
+ * Add historical data point
34
+ */
35
+ addDataPoint(metric, dataPoint) {
36
+ if (!this.historicalData.has(metric)) {
37
+ this.historicalData.set(metric, []);
38
+ }
39
+ this.historicalData.get(metric).push(dataPoint);
40
+ // Keep only data within lookback period
41
+ this.pruneOldData(metric);
42
+ }
43
+ /**
44
+ * Add multiple historical data points
45
+ */
46
+ addDataPoints(metric, dataPoints) {
47
+ for (const point of dataPoints) {
48
+ this.addDataPoint(metric, point);
49
+ }
50
+ }
51
+ /**
52
+ * Prune old data
53
+ */
54
+ pruneOldData(metric) {
55
+ const cutoff = new Date();
56
+ cutoff.setDate(cutoff.getDate() - this.options.lookbackDays);
57
+ const data = this.historicalData.get(metric);
58
+ if (data) {
59
+ this.historicalData.set(metric, data.filter(d => d.timestamp >= cutoff));
60
+ }
61
+ }
62
+ /**
63
+ * Import data from metrics
64
+ */
65
+ importFromMetrics(metrics) {
66
+ for (const metric of metrics) {
67
+ this.addDataPoint(metric.type, {
68
+ timestamp: metric.timestamp,
69
+ value: metric.value,
70
+ metadata: { breakdown: metric.breakdown },
71
+ });
72
+ }
73
+ }
74
+ /**
75
+ * Import data from vulnerability stats
76
+ */
77
+ importFromVulnStats(stats, timestamp = new Date()) {
78
+ this.addDataPoint('vulnerability-total', { timestamp, value: stats.total });
79
+ this.addDataPoint('vulnerability-critical', { timestamp, value: stats.bySeverity.critical });
80
+ this.addDataPoint('vulnerability-high', { timestamp, value: stats.bySeverity.high });
81
+ this.addDataPoint('vulnerability-medium', { timestamp, value: stats.bySeverity.medium });
82
+ this.addDataPoint('vulnerability-low', { timestamp, value: stats.bySeverity.low });
83
+ this.addDataPoint('vulnerability-new', { timestamp, value: stats.newInPeriod });
84
+ this.addDataPoint('vulnerability-fixed', { timestamp, value: stats.fixedInPeriod });
85
+ }
86
+ /**
87
+ * Project future risk
88
+ */
89
+ projectRisk(currentRiskScore, threatContext) {
90
+ const riskData = this.historicalData.get('average-risk-score') ?? [];
91
+ const projection = this.forecastValue(riskData, this.options.forecastDays);
92
+ let projectedRisk = projection.value;
93
+ const factors = [];
94
+ // Adjust based on trend
95
+ if (projection.trend === 'increasing') {
96
+ factors.push({
97
+ name: 'Historical Trend',
98
+ impact: projection.magnitude * 10,
99
+ description: 'Risk has been increasing based on historical data',
100
+ });
101
+ }
102
+ else if (projection.trend === 'decreasing') {
103
+ factors.push({
104
+ name: 'Historical Trend',
105
+ impact: -projection.magnitude * 10,
106
+ description: 'Risk has been decreasing based on historical data',
107
+ });
108
+ }
109
+ // Adjust based on threat context
110
+ if (threatContext?.activelyExploited) {
111
+ projectedRisk *= 1.5;
112
+ factors.push({
113
+ name: 'Active Exploitation',
114
+ impact: 50,
115
+ description: 'Vulnerabilities are actively being exploited in the wild',
116
+ });
117
+ }
118
+ if (threatContext?.urgency === 'immediate') {
119
+ projectedRisk *= 1.25;
120
+ factors.push({
121
+ name: 'Urgent Threat',
122
+ impact: 25,
123
+ description: 'Immediate remediation urgency indicated',
124
+ });
125
+ }
126
+ // Adjust based on vulnerability trends
127
+ const vulnData = this.historicalData.get('vulnerability-total') ?? [];
128
+ const vulnProjection = this.forecastValue(vulnData, this.options.forecastDays);
129
+ if (vulnProjection.trend === 'increasing') {
130
+ projectedRisk += vulnProjection.magnitude * 5;
131
+ factors.push({
132
+ name: 'Vulnerability Growth',
133
+ impact: vulnProjection.magnitude * 5,
134
+ description: 'Vulnerabilities are expected to increase',
135
+ });
136
+ }
137
+ // Cap risk at 100
138
+ projectedRisk = Math.min(100, Math.max(0, projectedRisk));
139
+ const change = projectedRisk - currentRiskScore;
140
+ const direction = change > 5 ? 'increasing' : change < -5 ? 'decreasing' : 'stable';
141
+ const confidence = this.calculateConfidence(riskData.length, projection.confidence);
142
+ const recommendations = this.generateRiskRecommendations(projectedRisk, factors);
143
+ // Create proactive alert if risk is increasing significantly
144
+ if (this.options.enableProactiveAlerts && change > this.options.alertThresholds.riskIncrease) {
145
+ this.createAlert({
146
+ type: 'risk-increase',
147
+ title: 'Risk Increase Projected',
148
+ message: `Risk is projected to increase from ${currentRiskScore} to ${Math.round(projectedRisk)} over the next ${this.options.forecastDays} days`,
149
+ severity: projectedRisk > 80 ? 'critical' : projectedRisk > 60 ? 'high' : 'medium',
150
+ actions: recommendations,
151
+ });
152
+ }
153
+ return {
154
+ id: `PROJ-${Date.now()}`,
155
+ currentRisk: currentRiskScore,
156
+ projectedRisk: Math.round(projectedRisk),
157
+ periodDays: this.options.forecastDays,
158
+ direction,
159
+ magnitude: Math.abs(change),
160
+ confidence,
161
+ confidenceScore: projection.confidence,
162
+ factors,
163
+ recommendations,
164
+ projectedAt: new Date(),
165
+ };
166
+ }
167
+ /**
168
+ * Forecast a value using simple linear regression
169
+ */
170
+ forecastValue(data, daysAhead) {
171
+ if (data.length < 2) {
172
+ return {
173
+ value: data[0]?.value ?? 0,
174
+ trend: 'stable',
175
+ magnitude: 0,
176
+ confidence: 0.3,
177
+ };
178
+ }
179
+ // Sort by timestamp
180
+ const sorted = [...data].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
181
+ // Calculate linear regression
182
+ const n = sorted.length;
183
+ let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
184
+ for (let i = 0; i < n; i++) {
185
+ sumX += i;
186
+ sumY += sorted[i].value;
187
+ sumXY += i * sorted[i].value;
188
+ sumX2 += i * i;
189
+ }
190
+ const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX) || 0;
191
+ const intercept = (sumY - slope * sumX) / n;
192
+ // Forecast
193
+ const forecastIndex = n + daysAhead;
194
+ const forecastValue = intercept + slope * forecastIndex;
195
+ // Determine trend
196
+ let trend;
197
+ if (Math.abs(slope) < 0.5) {
198
+ trend = 'stable';
199
+ }
200
+ else if (slope > 0) {
201
+ trend = 'increasing';
202
+ }
203
+ else {
204
+ trend = 'decreasing';
205
+ }
206
+ // Calculate R-squared for confidence
207
+ const yMean = sumY / n;
208
+ let ssTotal = 0, ssResidual = 0;
209
+ for (let i = 0; i < n; i++) {
210
+ const predicted = intercept + slope * i;
211
+ ssTotal += Math.pow(sorted[i].value - yMean, 2);
212
+ ssResidual += Math.pow(sorted[i].value - predicted, 2);
213
+ }
214
+ const rSquared = ssTotal > 0 ? 1 - (ssResidual / ssTotal) : 0;
215
+ return {
216
+ value: forecastValue,
217
+ trend,
218
+ magnitude: Math.abs(slope) * daysAhead,
219
+ confidence: Math.max(0.3, Math.min(0.95, rSquared)),
220
+ };
221
+ }
222
+ /**
223
+ * Calculate confidence level
224
+ */
225
+ calculateConfidence(dataPoints, statisticalConfidence) {
226
+ // Adjust for data availability
227
+ const dataFactor = Math.min(1, dataPoints / 20);
228
+ const overallConfidence = statisticalConfidence * dataFactor;
229
+ if (overallConfidence >= 0.8)
230
+ return 'high';
231
+ if (overallConfidence >= 0.6)
232
+ return 'medium';
233
+ if (overallConfidence >= 0.4)
234
+ return 'low';
235
+ return 'uncertain';
236
+ }
237
+ /**
238
+ * Generate risk recommendations
239
+ */
240
+ generateRiskRecommendations(projectedRisk, factors) {
241
+ const recommendations = [];
242
+ if (projectedRisk >= 80) {
243
+ recommendations.push('URGENT: Implement immediate risk mitigation measures');
244
+ recommendations.push('Prioritize critical and high severity vulnerabilities');
245
+ recommendations.push('Consider emergency patching procedures');
246
+ }
247
+ else if (projectedRisk >= 60) {
248
+ recommendations.push('Accelerate vulnerability remediation efforts');
249
+ recommendations.push('Review and update security controls');
250
+ recommendations.push('Increase monitoring frequency');
251
+ }
252
+ else if (projectedRisk >= 40) {
253
+ recommendations.push('Continue regular vulnerability management');
254
+ recommendations.push('Monitor for emerging threats');
255
+ }
256
+ // Factor-specific recommendations
257
+ for (const factor of factors) {
258
+ if (factor.name === 'Active Exploitation') {
259
+ recommendations.push('Deploy available patches immediately');
260
+ recommendations.push('Implement compensating controls if patches unavailable');
261
+ }
262
+ if (factor.name === 'Vulnerability Growth') {
263
+ recommendations.push('Investigate root cause of vulnerability increase');
264
+ recommendations.push('Review development security practices');
265
+ }
266
+ }
267
+ return recommendations;
268
+ }
269
+ /**
270
+ * Predict vulnerabilities
271
+ */
272
+ predictVulnerabilities() {
273
+ const predictions = [];
274
+ // Get current counts
275
+ const totalData = this.historicalData.get('vulnerability-total') ?? [];
276
+ const criticalData = this.historicalData.get('vulnerability-critical') ?? [];
277
+ const highData = this.historicalData.get('vulnerability-high') ?? [];
278
+ const newData = this.historicalData.get('vulnerability-new') ?? [];
279
+ // Predict total vulnerabilities
280
+ const totalForecast = this.forecastValue(totalData, this.options.forecastDays);
281
+ const currentTotal = totalData[totalData.length - 1]?.value ?? 0;
282
+ const predictedTotal = Math.max(0, Math.round(totalForecast.value));
283
+ predictions.push({
284
+ id: `PRED-TOTAL-${Date.now()}`,
285
+ type: 'all',
286
+ predictedCount: predictedTotal,
287
+ currentCount: currentTotal,
288
+ change: predictedTotal - currentTotal,
289
+ likelihood: totalForecast.confidence,
290
+ confidence: this.calculateConfidence(totalData.length, totalForecast.confidence),
291
+ timeFrame: this.options.forecastDays,
292
+ riskLevel: predictedTotal > currentTotal * 1.5 ? 'high' : 'medium',
293
+ preventionStrategies: this.getPreventionStrategies('all', totalForecast.trend),
294
+ });
295
+ // Predict critical vulnerabilities
296
+ const criticalForecast = this.forecastValue(criticalData, this.options.forecastDays);
297
+ const currentCritical = criticalData[criticalData.length - 1]?.value ?? 0;
298
+ const predictedCritical = Math.max(0, Math.round(criticalForecast.value));
299
+ if (predictedCritical > currentCritical) {
300
+ predictions.push({
301
+ id: `PRED-CRITICAL-${Date.now()}`,
302
+ type: 'critical',
303
+ predictedCount: predictedCritical,
304
+ currentCount: currentCritical,
305
+ change: predictedCritical - currentCritical,
306
+ likelihood: criticalForecast.confidence,
307
+ confidence: this.calculateConfidence(criticalData.length, criticalForecast.confidence),
308
+ timeFrame: this.options.forecastDays,
309
+ riskLevel: 'critical',
310
+ preventionStrategies: this.getPreventionStrategies('critical', criticalForecast.trend),
311
+ });
312
+ // Create alert for critical vulnerability surge
313
+ if (this.options.enableProactiveAlerts && predictedCritical > currentCritical * 1.5) {
314
+ this.createAlert({
315
+ type: 'vulnerability-surge',
316
+ title: 'Critical Vulnerability Surge Predicted',
317
+ message: `Critical vulnerabilities are expected to increase from ${currentCritical} to ${predictedCritical}`,
318
+ severity: 'critical',
319
+ actions: this.getPreventionStrategies('critical', 'increasing'),
320
+ });
321
+ }
322
+ }
323
+ // Predict high vulnerabilities
324
+ const highForecast = this.forecastValue(highData, this.options.forecastDays);
325
+ const currentHigh = highData[highData.length - 1]?.value ?? 0;
326
+ const predictedHigh = Math.max(0, Math.round(highForecast.value));
327
+ predictions.push({
328
+ id: `PRED-HIGH-${Date.now()}`,
329
+ type: 'high',
330
+ predictedCount: predictedHigh,
331
+ currentCount: currentHigh,
332
+ change: predictedHigh - currentHigh,
333
+ likelihood: highForecast.confidence,
334
+ confidence: this.calculateConfidence(highData.length, highForecast.confidence),
335
+ timeFrame: this.options.forecastDays,
336
+ riskLevel: 'high',
337
+ preventionStrategies: this.getPreventionStrategies('high', highForecast.trend),
338
+ });
339
+ // Predict new vulnerabilities per day
340
+ const newForecast = this.forecastValue(newData, this.options.forecastDays);
341
+ const currentNew = newData[newData.length - 1]?.value ?? 0;
342
+ const predictedNew = Math.max(0, Math.round(newForecast.value));
343
+ predictions.push({
344
+ id: `PRED-NEW-${Date.now()}`,
345
+ type: 'new-per-period',
346
+ predictedCount: predictedNew,
347
+ currentCount: currentNew,
348
+ change: predictedNew - currentNew,
349
+ likelihood: newForecast.confidence,
350
+ confidence: this.calculateConfidence(newData.length, newForecast.confidence),
351
+ timeFrame: this.options.forecastDays,
352
+ riskLevel: predictedNew > currentNew * 2 ? 'high' : 'medium',
353
+ preventionStrategies: this.getPreventionStrategies('new', newForecast.trend),
354
+ });
355
+ return predictions;
356
+ }
357
+ /**
358
+ * Get prevention strategies
359
+ */
360
+ getPreventionStrategies(type, trend) {
361
+ const strategies = [];
362
+ if (trend === 'increasing') {
363
+ strategies.push('Increase security code reviews');
364
+ strategies.push('Implement additional security testing');
365
+ strategies.push('Review and strengthen security training');
366
+ }
367
+ switch (type) {
368
+ case 'critical':
369
+ strategies.push('Prioritize critical vulnerability remediation');
370
+ strategies.push('Implement emergency patching procedures');
371
+ strategies.push('Deploy additional security monitoring');
372
+ break;
373
+ case 'high':
374
+ strategies.push('Accelerate high-severity fix deployment');
375
+ strategies.push('Review security architecture');
376
+ break;
377
+ case 'new':
378
+ strategies.push('Strengthen input validation practices');
379
+ strategies.push('Implement security linting in CI/CD');
380
+ strategies.push('Conduct security awareness training');
381
+ break;
382
+ default:
383
+ strategies.push('Continue regular security assessments');
384
+ strategies.push('Maintain vulnerability management processes');
385
+ }
386
+ return strategies;
387
+ }
388
+ /**
389
+ * Detect anomalies
390
+ */
391
+ detectAnomalies() {
392
+ const detected = [];
393
+ for (const [metric, data] of this.historicalData) {
394
+ if (data.length < 5)
395
+ continue; // Need minimum data
396
+ const anomaly = this.detectMetricAnomaly(metric, data);
397
+ if (anomaly) {
398
+ detected.push(anomaly);
399
+ this.anomalies.push(anomaly);
400
+ }
401
+ }
402
+ return detected;
403
+ }
404
+ /**
405
+ * Detect anomaly in a metric
406
+ */
407
+ detectMetricAnomaly(metric, data) {
408
+ const sorted = [...data].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
409
+ const values = sorted.map(d => d.value);
410
+ // Calculate mean and standard deviation
411
+ const mean = values.reduce((sum, v) => sum + v, 0) / values.length;
412
+ const stdDev = Math.sqrt(values.reduce((sum, v) => sum + Math.pow(v - mean, 2), 0) / values.length);
413
+ // Check latest value
414
+ const latestValue = values[values.length - 1];
415
+ const deviation = Math.abs(latestValue - mean);
416
+ const zScore = stdDev > 0 ? deviation / stdDev : 0;
417
+ // Anomaly threshold based on sensitivity
418
+ const threshold = 2 + (1 - this.options.anomalySensitivity) * 2;
419
+ if (zScore > threshold) {
420
+ const type = latestValue > mean ? 'spike' : 'drop';
421
+ const deviationPercent = (deviation / mean) * 100;
422
+ // Determine severity
423
+ let severity;
424
+ if (zScore > 4)
425
+ severity = 'critical';
426
+ else if (zScore > 3)
427
+ severity = 'high';
428
+ else if (zScore > 2.5)
429
+ severity = 'medium';
430
+ else
431
+ severity = 'low';
432
+ // Create alert
433
+ if (this.options.enableProactiveAlerts && deviationPercent > this.options.alertThresholds.deviationPercent) {
434
+ this.createAlert({
435
+ type: 'pattern-detected',
436
+ title: `Anomaly Detected in ${metric}`,
437
+ message: `${type === 'spike' ? 'Spike' : 'Drop'} of ${Math.round(deviationPercent)}% detected`,
438
+ severity,
439
+ actions: this.getAnomalyActions(type, metric),
440
+ });
441
+ }
442
+ return {
443
+ id: `ANOM-${Date.now()}`,
444
+ type,
445
+ metric,
446
+ expectedValue: mean,
447
+ actualValue: latestValue,
448
+ deviation,
449
+ severity,
450
+ confidence: Math.min(0.95, zScore / 5),
451
+ detectedAt: new Date(),
452
+ possibleCauses: this.getPossibleCauses(type, metric),
453
+ recommendedActions: this.getAnomalyActions(type, metric),
454
+ };
455
+ }
456
+ return null;
457
+ }
458
+ /**
459
+ * Get possible causes for anomaly
460
+ */
461
+ getPossibleCauses(type, metric) {
462
+ const causes = [];
463
+ if (type === 'spike') {
464
+ causes.push('New vulnerability scanner rules');
465
+ causes.push('Code deployment with security issues');
466
+ causes.push('New dependencies with vulnerabilities');
467
+ causes.push('Previously unreported issues discovered');
468
+ }
469
+ else if (type === 'drop') {
470
+ causes.push('Successful remediation campaign');
471
+ causes.push('False positives removed');
472
+ causes.push('Code refactoring');
473
+ causes.push('Data collection issues');
474
+ }
475
+ if (metric.includes('critical')) {
476
+ causes.push('Zero-day vulnerability discovered');
477
+ causes.push('Major security incident');
478
+ }
479
+ return causes;
480
+ }
481
+ /**
482
+ * Get recommended actions for anomaly
483
+ */
484
+ getAnomalyActions(type, metric) {
485
+ const actions = [];
486
+ actions.push('Investigate the root cause');
487
+ if (type === 'spike') {
488
+ actions.push('Review recent changes and deployments');
489
+ actions.push('Verify scanner accuracy');
490
+ actions.push('Prioritize triage of new findings');
491
+ }
492
+ else if (type === 'drop') {
493
+ actions.push('Verify data collection is functioning');
494
+ actions.push('Confirm remediation activities');
495
+ actions.push('Review for configuration issues');
496
+ }
497
+ if (metric.includes('critical') || metric.includes('high')) {
498
+ actions.push('Escalate to security team');
499
+ actions.push('Conduct emergency review');
500
+ }
501
+ return actions;
502
+ }
503
+ /**
504
+ * Create proactive alert
505
+ */
506
+ createAlert(params) {
507
+ const alert = {
508
+ id: `ALERT-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
509
+ type: params.type,
510
+ title: params.title,
511
+ message: params.message,
512
+ severity: params.severity,
513
+ confidence: 'medium',
514
+ timeToImpact: params.timeToImpact,
515
+ actions: params.actions,
516
+ relatedPredictions: [],
517
+ createdAt: new Date(),
518
+ };
519
+ this.alerts.push(alert);
520
+ return alert;
521
+ }
522
+ /**
523
+ * Get all alerts
524
+ */
525
+ getAlerts() {
526
+ return [...this.alerts];
527
+ }
528
+ /**
529
+ * Get alerts by severity
530
+ */
531
+ getAlertsBySeverity(severity) {
532
+ return this.alerts.filter(a => a.severity === severity);
533
+ }
534
+ /**
535
+ * Clear old alerts
536
+ */
537
+ clearOldAlerts(maxAgeDays = 7) {
538
+ const cutoff = new Date();
539
+ cutoff.setDate(cutoff.getDate() - maxAgeDays);
540
+ const before = this.alerts.length;
541
+ this.alerts = this.alerts.filter(a => a.createdAt >= cutoff);
542
+ return before - this.alerts.length;
543
+ }
544
+ /**
545
+ * Generate security forecast
546
+ */
547
+ generateForecast() {
548
+ const now = new Date();
549
+ const endDate = new Date(now);
550
+ endDate.setDate(endDate.getDate() + this.options.forecastDays);
551
+ // Get projections
552
+ const currentRisk = this.historicalData.get('average-risk-score');
553
+ const latestRisk = currentRisk?.[currentRisk.length - 1]?.value ?? 50;
554
+ const riskProjection = this.projectRisk(latestRisk);
555
+ // Get vulnerability predictions
556
+ const vulnPredictions = this.predictVulnerabilities();
557
+ // Detect anomalies
558
+ this.detectAnomalies();
559
+ // Calculate expected trends
560
+ const expectedTrends = [];
561
+ for (const [metric, data] of this.historicalData) {
562
+ const forecast = this.forecastValue(data, this.options.forecastDays);
563
+ expectedTrends.push({
564
+ metric,
565
+ direction: forecast.trend === 'stable' ? 'stable' : forecast.trend === 'increasing' ? 'up' : 'down',
566
+ magnitude: forecast.magnitude,
567
+ confidence: forecast.confidence,
568
+ });
569
+ }
570
+ // Identify key risks
571
+ const keyRisks = [];
572
+ if (riskProjection.direction === 'increasing') {
573
+ keyRisks.push(`Risk projected to increase by ${Math.round(riskProjection.magnitude)} points`);
574
+ }
575
+ for (const pred of vulnPredictions.filter(p => p.riskLevel === 'critical' && p.change > 0)) {
576
+ keyRisks.push(`${pred.type} vulnerabilities expected to increase`);
577
+ }
578
+ // Identify opportunities
579
+ const opportunities = [];
580
+ if (riskProjection.direction === 'decreasing') {
581
+ opportunities.push('Risk is trending downward - maintain momentum');
582
+ }
583
+ const fixData = this.historicalData.get('vulnerability-fixed');
584
+ if (fixData && fixData.length > 0) {
585
+ const avgFixes = fixData.reduce((sum, d) => sum + d.value, 0) / fixData.length;
586
+ if (avgFixes > 5) {
587
+ opportunities.push(`Strong remediation velocity (${Math.round(avgFixes)} fixes/period)`);
588
+ }
589
+ }
590
+ // Aggregate recommendations
591
+ const recommendations = [
592
+ ...riskProjection.recommendations.slice(0, 3),
593
+ ...vulnPredictions.flatMap(p => p.preventionStrategies.slice(0, 2)),
594
+ ].filter((rec, i, arr) => arr.indexOf(rec) === i).slice(0, 10);
595
+ return {
596
+ id: `FORECAST-${Date.now()}`,
597
+ period: {
598
+ start: now,
599
+ end: endDate,
600
+ },
601
+ riskProjections: [riskProjection],
602
+ vulnerabilityPredictions: vulnPredictions,
603
+ expectedTrends,
604
+ keyRisks,
605
+ opportunities,
606
+ recommendations,
607
+ generatedAt: now,
608
+ };
609
+ }
610
+ /**
611
+ * Get statistics
612
+ */
613
+ getStatistics() {
614
+ let dataPointsCount = 0;
615
+ let oldestData = null;
616
+ let latestData = null;
617
+ for (const data of this.historicalData.values()) {
618
+ dataPointsCount += data.length;
619
+ for (const point of data) {
620
+ if (!oldestData || point.timestamp < oldestData) {
621
+ oldestData = point.timestamp;
622
+ }
623
+ if (!latestData || point.timestamp > latestData) {
624
+ latestData = point.timestamp;
625
+ }
626
+ }
627
+ }
628
+ return {
629
+ dataPointsCount,
630
+ metricsTracked: this.historicalData.size,
631
+ alertsCount: this.alerts.length,
632
+ anomaliesCount: this.anomalies.length,
633
+ oldestData,
634
+ latestData,
635
+ };
636
+ }
637
+ /**
638
+ * Get anomalies
639
+ */
640
+ getAnomalies() {
641
+ return [...this.anomalies];
642
+ }
643
+ /**
644
+ * Export data
645
+ */
646
+ exportData() {
647
+ return {
648
+ historicalData: Object.fromEntries(this.historicalData),
649
+ alerts: [...this.alerts],
650
+ anomalies: [...this.anomalies],
651
+ };
652
+ }
653
+ /**
654
+ * Import data
655
+ */
656
+ importData(data) {
657
+ if (data.historicalData) {
658
+ for (const [metric, points] of Object.entries(data.historicalData)) {
659
+ this.historicalData.set(metric, points.map(p => ({
660
+ ...p,
661
+ timestamp: new Date(p.timestamp),
662
+ })));
663
+ }
664
+ }
665
+ if (data.alerts) {
666
+ this.alerts = data.alerts.map(a => ({
667
+ ...a,
668
+ createdAt: new Date(a.createdAt),
669
+ }));
670
+ }
671
+ if (data.anomalies) {
672
+ this.anomalies = data.anomalies.map(a => ({
673
+ ...a,
674
+ detectedAt: new Date(a.detectedAt),
675
+ }));
676
+ }
677
+ }
678
+ }
679
+ // ============================================================================
680
+ // Factory Functions
681
+ // ============================================================================
682
+ /**
683
+ * Create a PredictiveAnalyzer instance
684
+ */
685
+ export function createPredictiveAnalyzer(options) {
686
+ return new PredictiveAnalyzer(options);
687
+ }
688
+ /**
689
+ * Quick risk projection
690
+ */
691
+ export function projectRisk(currentRisk, historicalData) {
692
+ const analyzer = createPredictiveAnalyzer();
693
+ analyzer.addDataPoints('average-risk-score', historicalData);
694
+ return analyzer.projectRisk(currentRisk);
695
+ }
696
+ /**
697
+ * Quick vulnerability prediction
698
+ */
699
+ export function predictVulnerabilities(vulnStats) {
700
+ const analyzer = createPredictiveAnalyzer();
701
+ for (const stats of vulnStats) {
702
+ analyzer.importFromVulnStats(stats);
703
+ }
704
+ return analyzer.predictVulnerabilities();
705
+ }
706
+ /**
707
+ * Quick anomaly detection
708
+ */
709
+ export function detectAnomalies(metrics) {
710
+ const analyzer = createPredictiveAnalyzer();
711
+ analyzer.importFromMetrics(metrics);
712
+ return analyzer.detectAnomalies();
713
+ }
714
+ //# sourceMappingURL=predictive-analyzer.js.map