@nahisaho/musubix-security 1.8.0 → 1.8.1
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/README.md +27 -0
- package/dist/analyzers/ai/index.d.ts +6 -0
- package/dist/analyzers/ai/index.d.ts.map +1 -0
- package/dist/analyzers/ai/index.js +6 -0
- package/dist/analyzers/ai/index.js.map +1 -0
- package/dist/analyzers/ai/prompt-injection-detector.d.ts +152 -0
- package/dist/analyzers/ai/prompt-injection-detector.d.ts.map +1 -0
- package/dist/analyzers/ai/prompt-injection-detector.js +468 -0
- package/dist/analyzers/ai/prompt-injection-detector.js.map +1 -0
- package/dist/analyzers/api/api-security-analyzer.d.ts +263 -0
- package/dist/analyzers/api/api-security-analyzer.d.ts.map +1 -0
- package/dist/analyzers/api/api-security-analyzer.js +581 -0
- package/dist/analyzers/api/api-security-analyzer.js.map +1 -0
- package/dist/analyzers/compliance/compliance-checker.d.ts +201 -0
- package/dist/analyzers/compliance/compliance-checker.d.ts.map +1 -0
- package/dist/analyzers/compliance/compliance-checker.js +772 -0
- package/dist/analyzers/compliance/compliance-checker.js.map +1 -0
- package/dist/analyzers/container/image-scanner.d.ts +163 -0
- package/dist/analyzers/container/image-scanner.d.ts.map +1 -0
- package/dist/analyzers/container/image-scanner.js +459 -0
- package/dist/analyzers/container/image-scanner.js.map +1 -0
- package/dist/analyzers/container/index.d.ts +6 -0
- package/dist/analyzers/container/index.d.ts.map +1 -0
- package/dist/analyzers/container/index.js +6 -0
- package/dist/analyzers/container/index.js.map +1 -0
- package/dist/analyzers/dashboard/security-dashboard.d.ts +286 -0
- package/dist/analyzers/dashboard/security-dashboard.d.ts.map +1 -0
- package/dist/analyzers/dashboard/security-dashboard.js +796 -0
- package/dist/analyzers/dashboard/security-dashboard.js.map +1 -0
- package/dist/analyzers/iac/iac-checker.d.ts +124 -0
- package/dist/analyzers/iac/iac-checker.d.ts.map +1 -0
- package/dist/analyzers/iac/iac-checker.js +755 -0
- package/dist/analyzers/iac/iac-checker.js.map +1 -0
- package/dist/analyzers/iac/index.d.ts +6 -0
- package/dist/analyzers/iac/index.d.ts.map +1 -0
- package/dist/analyzers/iac/index.js +6 -0
- package/dist/analyzers/iac/index.js.map +1 -0
- package/dist/analyzers/index.d.ts +9 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +13 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/monitor/realtime-monitor.d.ts +216 -0
- package/dist/analyzers/monitor/realtime-monitor.d.ts.map +1 -0
- package/dist/analyzers/monitor/realtime-monitor.js +601 -0
- package/dist/analyzers/monitor/realtime-monitor.js.map +1 -0
- package/dist/analyzers/sast/index.d.ts +7 -0
- package/dist/analyzers/sast/index.d.ts.map +1 -0
- package/dist/analyzers/sast/index.js +7 -0
- package/dist/analyzers/sast/index.js.map +1 -0
- package/dist/analyzers/sast/interprocedural-analyzer.d.ts +276 -0
- package/dist/analyzers/sast/interprocedural-analyzer.d.ts.map +1 -0
- package/dist/analyzers/sast/interprocedural-analyzer.js +635 -0
- package/dist/analyzers/sast/interprocedural-analyzer.js.map +1 -0
- package/dist/analyzers/sast/zero-day-detector.d.ts +183 -0
- package/dist/analyzers/sast/zero-day-detector.d.ts.map +1 -0
- package/dist/analyzers/sast/zero-day-detector.js +593 -0
- package/dist/analyzers/sast/zero-day-detector.js.map +1 -0
- package/dist/analyzers/sca/dependency-scanner.d.ts +275 -0
- package/dist/analyzers/sca/dependency-scanner.d.ts.map +1 -0
- package/dist/analyzers/sca/dependency-scanner.js +642 -0
- package/dist/analyzers/sca/dependency-scanner.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +10 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/pipeline-manager.d.ts +105 -0
- package/dist/core/pipeline-manager.d.ts.map +1 -0
- package/dist/core/pipeline-manager.js +449 -0
- package/dist/core/pipeline-manager.js.map +1 -0
- package/dist/core/result-aggregator.d.ts +96 -0
- package/dist/core/result-aggregator.d.ts.map +1 -0
- package/dist/core/result-aggregator.js +462 -0
- package/dist/core/result-aggregator.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +68 -0
- package/dist/index.js.map +1 -1
- package/dist/integrations/ci-integration.d.ts +227 -0
- package/dist/integrations/ci-integration.d.ts.map +1 -0
- package/dist/integrations/ci-integration.js +472 -0
- package/dist/integrations/ci-integration.js.map +1 -0
- package/dist/integrations/git-hooks.d.ts +155 -0
- package/dist/integrations/git-hooks.d.ts.map +1 -0
- package/dist/integrations/git-hooks.js +425 -0
- package/dist/integrations/git-hooks.js.map +1 -0
- package/dist/integrations/index.d.ts +9 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +9 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/report-aggregator.d.ts +250 -0
- package/dist/integrations/report-aggregator.d.ts.map +1 -0
- package/dist/integrations/report-aggregator.js +488 -0
- package/dist/integrations/report-aggregator.js.map +1 -0
- package/dist/integrations/vscode-integration.d.ts +245 -0
- package/dist/integrations/vscode-integration.d.ts.map +1 -0
- package/dist/integrations/vscode-integration.js +449 -0
- package/dist/integrations/vscode-integration.js.map +1 -0
- package/dist/intelligence/attack-pattern-matcher.d.ts +217 -0
- package/dist/intelligence/attack-pattern-matcher.d.ts.map +1 -0
- package/dist/intelligence/attack-pattern-matcher.js +887 -0
- package/dist/intelligence/attack-pattern-matcher.js.map +1 -0
- package/dist/intelligence/index.d.ts +12 -0
- package/dist/intelligence/index.d.ts.map +1 -0
- package/dist/intelligence/index.js +18 -0
- package/dist/intelligence/index.js.map +1 -0
- package/dist/intelligence/neuro-symbolic-core.d.ts +88 -0
- package/dist/intelligence/neuro-symbolic-core.d.ts.map +1 -0
- package/dist/intelligence/neuro-symbolic-core.js +403 -0
- package/dist/intelligence/neuro-symbolic-core.js.map +1 -0
- package/dist/intelligence/predictive-analyzer.d.ts +317 -0
- package/dist/intelligence/predictive-analyzer.d.ts.map +1 -0
- package/dist/intelligence/predictive-analyzer.js +714 -0
- package/dist/intelligence/predictive-analyzer.js.map +1 -0
- package/dist/intelligence/risk-scorer.d.ts +333 -0
- package/dist/intelligence/risk-scorer.d.ts.map +1 -0
- package/dist/intelligence/risk-scorer.js +824 -0
- package/dist/intelligence/risk-scorer.js.map +1 -0
- package/dist/intelligence/security-analytics.d.ts +349 -0
- package/dist/intelligence/security-analytics.d.ts.map +1 -0
- package/dist/intelligence/security-analytics.js +813 -0
- package/dist/intelligence/security-analytics.js.map +1 -0
- package/dist/intelligence/threat-intelligence.d.ts +288 -0
- package/dist/intelligence/threat-intelligence.d.ts.map +1 -0
- package/dist/intelligence/threat-intelligence.js +639 -0
- package/dist/intelligence/threat-intelligence.js.map +1 -0
- package/dist/policy/index.d.ts +6 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +6 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/policy-engine.d.ts +254 -0
- package/dist/policy/policy-engine.d.ts.map +1 -0
- package/dist/policy/policy-engine.js +651 -0
- package/dist/policy/policy-engine.js.map +1 -0
- package/dist/remediation/auto-fixer.d.ts +179 -0
- package/dist/remediation/auto-fixer.d.ts.map +1 -0
- package/dist/remediation/auto-fixer.js +540 -0
- package/dist/remediation/auto-fixer.js.map +1 -0
- package/dist/remediation/fix-validator.d.ts +195 -0
- package/dist/remediation/fix-validator.d.ts.map +1 -0
- package/dist/remediation/fix-validator.js +462 -0
- package/dist/remediation/fix-validator.js.map +1 -0
- package/dist/remediation/index.d.ts +10 -0
- package/dist/remediation/index.d.ts.map +1 -0
- package/dist/remediation/index.js +15 -0
- package/dist/remediation/index.js.map +1 -0
- package/dist/remediation/patch-generator.d.ts +203 -0
- package/dist/remediation/patch-generator.d.ts.map +1 -0
- package/dist/remediation/patch-generator.js +533 -0
- package/dist/remediation/patch-generator.js.map +1 -0
- package/dist/remediation/remediation-planner.d.ts +262 -0
- package/dist/remediation/remediation-planner.d.ts.map +1 -0
- package/dist/remediation/remediation-planner.js +531 -0
- package/dist/remediation/remediation-planner.js.map +1 -0
- package/dist/remediation/secure-code-transformer.d.ts +222 -0
- package/dist/remediation/secure-code-transformer.d.ts.map +1 -0
- package/dist/remediation/secure-code-transformer.js +625 -0
- package/dist/remediation/secure-code-transformer.js.map +1 -0
- package/dist/types/fix.d.ts +3 -1
- package/dist/types/fix.d.ts.map +1 -1
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/interprocedural.d.ts +203 -0
- package/dist/types/interprocedural.d.ts.map +1 -0
- package/dist/types/interprocedural.js +7 -0
- package/dist/types/interprocedural.js.map +1 -0
- package/dist/types/neuro-symbolic.d.ts +179 -0
- package/dist/types/neuro-symbolic.d.ts.map +1 -0
- package/dist/types/neuro-symbolic.js +7 -0
- package/dist/types/neuro-symbolic.js.map +1 -0
- package/dist/types/pipeline.d.ts +173 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +7 -0
- package/dist/types/pipeline.js.map +1 -0
- package/dist/types/result.d.ts +134 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +25 -0
- package/dist/types/result.js.map +1 -0
- package/dist/types/vulnerability.d.ts +2 -2
- package/dist/types/vulnerability.d.ts.map +1 -1
- package/dist/types/zero-day.d.ts +146 -0
- package/dist/types/zero-day.d.ts.map +1 -0
- package/dist/types/zero-day.js +7 -0
- package/dist/types/zero-day.js.map +1 -0
- 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
|