UNPKG

@iota-big3/sdk-security

Version:

Advanced security features including zero trust, quantum-safe crypto, and ML threat detection

550 lines 20.6 kB
"use strict"; /** * Automated Incident Detector * Monitors security events and automatically creates incidents */ Object.defineProperty(exports, "__esModule", { value: true }); exports.AutomatedIncidentDetector = void 0; const events_1 = require("events"); const types_1 = require("./types"); class AutomatedIncidentDetector extends events_1.EventEmitter { constructor(irManager) { super(); this.rules = new Map(); this.correlationWindows = new Map(); this.eventBuffer = []; this.isRunning = false; this.irManager = irManager; this.initializeDefaultRules(); } /** * Start the detector */ start() { if (this.isRunning) return; this.isRunning = true; // Process events every 5 seconds this.processInterval = setInterval(() => { this.processEventBuffer(); }, 5000); this.emit('started'); } /** * Stop the detector */ stop() { if (!this.isRunning) return; this.isRunning = false; if (this.processInterval) { clearInterval(this.processInterval); this.processInterval = undefined; } this.emit('stopped'); } /** * Process security event */ async processSecurityEvent(event) { if (!this.isRunning) return; // Add to buffer for batch processing this.eventBuffer.push(event); // Check for high-severity events that need immediate processing if (this.isHighPriority(event)) { await this.processEventBuffer(); } } /** * Process SIEM alert */ async processSIEMAlert(alert) { if (!this.isRunning) return; // SIEM alerts often indicate confirmed threats const incident = await this.createIncidentFromSIEMAlert(alert); if (incident) { this.emit('incident:auto-created', { incident, source: 'siem-alert', alert }); } } /** * Process threat indicator match */ async processThreatIndicator(indicator, context) { if (!this.isRunning) return; const incident = await this.irManager.createIncident({ title: `Threat Indicator Match: ${indicator.value}`, description: `Matched threat indicator ${indicator.type}: ${indicator.value} from ${indicator.source}`, type: this.mapIndicatorToIncidentType(indicator), severity: this.calculateSeverityFromThreatScore(indicator.confidence), source: types_1.IncidentSource.THREAT_INTEL, affectedSystems: context.systems || [], tags: ['threat-intel', 'ioc-match', indicator.type.toLowerCase()], customFields: { indicator, context } }); this.emit('incident:auto-created', { incident, source: 'threat-indicator', indicator }); } /** * Add detection rule */ addRule(rule) { this.rules.set(rule.id, rule); this.emit('rule:added', rule); } /** * Remove detection rule */ removeRule(ruleId) { this.rules.delete(ruleId); this.correlationWindows.delete(ruleId); this.emit('rule:removed', ruleId); } /** * Get all rules */ getRules() { return Array.from(this.rules.values()); } /** * Private methods */ initializeDefaultRules() { // Brute force detection this.addRule({ id: 'rule-brute-force', name: 'Brute Force Attack Detection', description: 'Detects multiple failed login attempts', enabled: true, conditions: [ { field: 'type', operator: 'equals', value: 'AUTHENTICATION_FAILURE' } ], incidentConfig: { type: types_1.IncidentType.UNAUTHORIZED_ACCESS, severity: types_1.IncidentSeverity.HIGH, titleTemplate: 'Brute Force Attack Detected: {{target}}', descriptionTemplate: 'Multiple failed login attempts detected from {{source}} to {{target}}', tags: ['brute-force', 'authentication'] }, correlation: { timeWindow: 300, // 5 minutes minEvents: 5, groupBy: ['source', 'target'] } }); // Data exfiltration detection this.addRule({ id: 'rule-data-exfil', name: 'Data Exfiltration Detection', description: 'Detects large data transfers to external destinations', enabled: true, conditions: [ { field: 'type', operator: 'equals', value: 'NETWORK_TRAFFIC' }, { field: 'bytes_out', operator: 'greater', value: 1073741824, // 1GB logic: 'AND' }, { field: 'destination.external', operator: 'equals', value: true, logic: 'AND' } ], incidentConfig: { type: types_1.IncidentType.DATA_BREACH, severity: types_1.IncidentSeverity.CRITICAL, titleTemplate: 'Potential Data Exfiltration: {{source}}', descriptionTemplate: 'Large data transfer detected from {{source}} to external destination {{destination}}', tags: ['data-exfiltration', 'dlp'] } }); // Malware detection this.addRule({ id: 'rule-malware', name: 'Malware Detection', description: 'Detects malware signatures and behaviors', enabled: true, conditions: [ { field: 'type', operator: 'in', value: ['MALWARE_DETECTED', 'SUSPICIOUS_PROCESS', 'FILE_INTEGRITY_VIOLATION'] } ], incidentConfig: { type: types_1.IncidentType.MALWARE, severity: types_1.IncidentSeverity.HIGH, titleTemplate: 'Malware Detected: {{malware.name}}', descriptionTemplate: 'Malware {{malware.name}} detected on {{host}}', tags: ['malware', 'endpoint-security'] } }); // Privilege escalation this.addRule({ id: 'rule-priv-escalation', name: 'Privilege Escalation Detection', description: 'Detects unauthorized privilege escalation attempts', enabled: true, conditions: [ { field: 'type', operator: 'equals', value: 'PRIVILEGE_ESCALATION' } ], incidentConfig: { type: types_1.IncidentType.UNAUTHORIZED_ACCESS, severity: types_1.IncidentSeverity.CRITICAL, titleTemplate: 'Privilege Escalation: {{user}}', descriptionTemplate: 'User {{user}} attempted unauthorized privilege escalation on {{system}}', tags: ['privilege-escalation', 'insider-threat'] } }); // Suspicious network activity this.addRule({ id: 'rule-suspicious-network', name: 'Suspicious Network Activity', description: 'Detects anomalous network behavior', enabled: true, conditions: [ { field: 'type', operator: 'equals', value: 'NETWORK_ANOMALY' }, { field: 'risk_score', operator: 'greater', value: 75, logic: 'AND' } ], incidentConfig: { type: types_1.IncidentType.OTHER, severity: types_1.IncidentSeverity.MEDIUM, titleTemplate: 'Suspicious Network Activity: {{source}}', descriptionTemplate: 'Anomalous network behavior detected from {{source}}', tags: ['network-anomaly', 'suspicious-activity'] } }); // Compliance violation this.addRule({ id: 'rule-compliance', name: 'Compliance Violation Detection', description: 'Detects violations of compliance policies', enabled: true, conditions: [ { field: 'type', operator: 'equals', value: 'COMPLIANCE_VIOLATION' } ], incidentConfig: { type: types_1.IncidentType.COMPLIANCE_VIOLATION, severity: types_1.IncidentSeverity.HIGH, titleTemplate: 'Compliance Violation: {{policy}}', descriptionTemplate: 'Violation of {{policy}} policy detected: {{violation.details}}', tags: ['compliance', 'policy-violation'] } }); } async processEventBuffer() { if (this.eventBuffer.length === 0) return; // Take current buffer and clear it const events = [...this.eventBuffer]; this.eventBuffer = []; // Process each event against rules for (const event of events) { await this.evaluateRules(event); } // Check correlation windows await this.checkCorrelations(); } async evaluateRules(event) { for (const rule of this.rules.values()) { if (!rule.enabled) continue; if (this.matchesConditions(event, rule.conditions)) { if (rule.correlation) { // Add to correlation window this.addToCorrelation(rule, event); } else { // Create incident immediately await this.createIncidentFromRule(rule, [event]); } } } } matchesConditions(event, conditions) { let result = true; let logic = 'AND'; for (const condition of conditions) { const fieldValue = this.getFieldValue(event, condition.field); const matches = this.evaluateCondition(fieldValue, condition.operator, condition.value); if (logic === 'AND') { result = result && matches; } else { result = result || matches; } logic = condition.logic || 'AND'; } return result; } getFieldValue(obj, field) { // Support nested fields like 'user.name' const parts = field.split('.'); let value = obj; for (const part of parts) { value = value?.[part]; } return value; } evaluateCondition(fieldValue, operator, conditionValue) { switch (operator) { case 'equals': return fieldValue === conditionValue; case 'contains': return String(fieldValue).includes(String(conditionValue)); case 'greater': return Number(fieldValue) > Number(conditionValue); case 'less': return Number(fieldValue) < Number(conditionValue); case 'matches': return new RegExp(conditionValue).test(String(fieldValue)); case 'in': return Array.isArray(conditionValue) && conditionValue.includes(fieldValue); default: return false; } } addToCorrelation(rule, event) { if (!rule.correlation) return; const windows = this.correlationWindows.get(rule.id) || []; const now = new Date(); // Find or create correlation window const groupKey = this.getCorrelationGroupKey(event, rule.correlation.groupBy); let window = windows.find(w => w.startTime.getTime() + rule.correlation.timeWindow * 1000 > now.getTime() && this.getCorrelationGroupKey(w.events[0], rule.correlation.groupBy) === groupKey); if (!window) { window = { ruleId: rule.id, events: [], startTime: now, endTime: new Date(now.getTime() + rule.correlation.timeWindow * 1000) }; windows.push(window); } window.events.push(event); this.correlationWindows.set(rule.id, windows); } getCorrelationGroupKey(event, groupBy) { if (!groupBy || groupBy.length === 0) return 'default'; const values = groupBy.map(field => this.getFieldValue(event, field)); return values.join('|'); } async checkCorrelations() { const now = new Date(); for (const [ruleId, windows] of this.correlationWindows) { const rule = this.rules.get(ruleId); if (!rule || !rule.correlation) continue; // Check each window const activeWindows = []; for (const window of windows) { if (window.endTime > now) { // Window still active if (window.events.length >= rule.correlation.minEvents) { // Threshold reached, create incident await this.createIncidentFromRule(rule, window.events); // Don't include this window in active windows } else { activeWindows.push(window); } } // else window expired, remove it } this.correlationWindows.set(ruleId, activeWindows); } } async createIncidentFromRule(rule, events) { const firstEvent = events[0]; const context = this.extractContext(events); const title = this.processTemplate(rule.incidentConfig.titleTemplate, context); const description = this.processTemplate(rule.incidentConfig.descriptionTemplate, context); const incident = await this.irManager.createIncident({ title, description, type: rule.incidentConfig.type, severity: rule.incidentConfig.severity, source: types_1.IncidentSource.AUTOMATED_DETECTION, affectedSystems: context.systems || [], affectedUsers: context.users || [], tags: [...rule.incidentConfig.tags, 'auto-detected', `rule:${rule.id}`], customFields: { detectionRule: rule, triggeringEvents: events, eventCount: events.length } }); this.emit('incident:auto-created', { incident, source: 'detection-rule', rule, events }); } async createIncidentFromSIEMAlert(alert) { // Map SIEM severity to incident severity const severity = this.mapSIEMSeverity(alert.severity); // Skip low-priority alerts unless configured if (severity === types_1.IncidentSeverity.LOW || severity === types_1.IncidentSeverity.INFO) { return null; } const incident = await this.irManager.createIncident({ title: alert.title, description: alert.description, type: this.mapSIEMAlertType(alert), severity, source: types_1.IncidentSource.SIEM, affectedSystems: alert.affectedAssets || [], tags: ['siem-alert', alert.platform.toLowerCase(), ...alert.tags], customFields: { siemAlert: alert, siemId: alert.id, siemPlatform: alert.platform } }); return incident; } extractContext(events) { const context = {}; const systems = new Set(); const users = new Set(); const sources = new Set(); for (const event of events) { // Extract common fields if ('system' in event && event.system) systems.add(event.system); if ('host' in event && event.host) systems.add(event.host); if ('user' in event && event.user) users.add(event.user); if ('source' in event && event.source) sources.add(event.source); if ('sourceIP' in event && event.sourceIP) sources.add(event.sourceIP); // Copy first event's fields as base context if (events.indexOf(event) === 0) { Object.assign(context, event); } } context.systems = Array.from(systems); context.users = Array.from(users); context.sources = Array.from(sources); context.eventCount = events.length; return context; } processTemplate(template, context) { return template.replace(/\{\{([^}]+)\}\}/g, (match, key) => { const value = this.getFieldValue(context, key.trim()); return value !== undefined ? String(value) : match; }); } isHighPriority(event) { // Check if event requires immediate processing return event.severity === 'CRITICAL' || event.type === 'MALWARE_DETECTED' || event.type === 'DATA_BREACH' || event.risk_score > 90; } mapIndicatorToIncidentType(indicator) { // Map threat indicator types to incident types if (indicator.tags?.includes('ransomware')) return types_1.IncidentType.RANSOMWARE; if (indicator.tags?.includes('phishing')) return types_1.IncidentType.PHISHING; if (indicator.tags?.includes('malware')) return types_1.IncidentType.MALWARE; if (indicator.type === 'IP' || indicator.type === 'DOMAIN') return types_1.IncidentType.UNAUTHORIZED_ACCESS; return types_1.IncidentType.OTHER; } calculateSeverityFromThreatScore(score) { if (score >= 90) return types_1.IncidentSeverity.CRITICAL; if (score >= 70) return types_1.IncidentSeverity.HIGH; if (score >= 50) return types_1.IncidentSeverity.MEDIUM; if (score >= 30) return types_1.IncidentSeverity.LOW; return types_1.IncidentSeverity.INFO; } mapSIEMSeverity(siemSeverity) { const severityMap = { 'critical': types_1.IncidentSeverity.CRITICAL, 'high': types_1.IncidentSeverity.HIGH, 'medium': types_1.IncidentSeverity.MEDIUM, 'low': types_1.IncidentSeverity.LOW, 'info': types_1.IncidentSeverity.INFO, 'informational': types_1.IncidentSeverity.INFO }; return severityMap[siemSeverity.toLowerCase()] || types_1.IncidentSeverity.MEDIUM; } mapSIEMAlertType(alert) { // Map based on alert categories or tags const title = alert.title.toLowerCase(); const tags = alert.tags.map(t => t.toLowerCase()); if (title.includes('ransomware') || tags.includes('ransomware')) { return types_1.IncidentType.RANSOMWARE; } if (title.includes('malware') || tags.includes('malware')) { return types_1.IncidentType.MALWARE; } if (title.includes('phishing') || tags.includes('phishing')) { return types_1.IncidentType.PHISHING; } if (title.includes('ddos') || title.includes('denial of service')) { return types_1.IncidentType.DENIAL_OF_SERVICE; } if (title.includes('breach') || tags.includes('data-breach')) { return types_1.IncidentType.DATA_BREACH; } if (title.includes('unauthorized') || title.includes('authentication')) { return types_1.IncidentType.UNAUTHORIZED_ACCESS; } return types_1.IncidentType.OTHER; } } exports.AutomatedIncidentDetector = AutomatedIncidentDetector; //# sourceMappingURL=automated-detector.js.map