@iota-big3/sdk-security
Version:
Advanced security features including zero trust, quantum-safe crypto, and ML threat detection
550 lines • 20.6 kB
JavaScript
"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