UNPKG

@iota-big3/sdk-security

Version:

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

471 lines 16.4 kB
"use strict"; /** * SIEM Connector Factory * Creates connectors for various SIEM platforms */ Object.defineProperty(exports, "__esModule", { value: true }); exports.SIEMConnectorFactory = void 0; const events_1 = require("events"); const types_1 = require("./types"); /** * Base SIEM connector with common functionality */ class BaseSIEMConnector extends events_1.EventEmitter { constructor(config) { super(); this.connected = false; this.eventQueue = []; this.stats = { eventsSent: 0, eventsQueued: 0, errors: 0, lastError: undefined, lastConnected: undefined }; this.config = config; this.setupBatchProcessing(); } async sendEvent(event) { if (!this.config.enabled) return; // Apply filters if (this.shouldFilter(event)) return; // Add to queue this.eventQueue.push(event); this.stats.eventsQueued++; // Send immediately if batch size reached if (this.eventQueue.length >= (this.config.batchSize || 100)) { await this.flush(); } } async testConnection() { try { await this.connect(); const testEvent = { version: '1.0', deviceVendor: 'IOTA Big3', deviceProduct: 'SDK Security', deviceVersion: '1.0.0', signatureId: 'TEST-001', name: 'Connection Test', severity: types_1.SIEMSeverity.INFORMATIONAL, timestamp: new Date(), eventType: types_1.SIEMEventType.SYSTEM, message: 'SIEM connection test' }; await this.sendEvent(testEvent); return true; } catch (error) { this.handleError(error); return false; } } getStatus() { return { connected: this.connected, lastConnected: this.stats.lastConnected, eventsSent: this.stats.eventsSent, eventsQueued: this.stats.eventsQueued, errors: this.stats.errors, lastError: this.stats.lastError }; } setupBatchProcessing() { if (this.config.flushInterval) { this.batchTimer = setInterval(() => { this.flush().catch(err => this.handleError(err)); }, this.config.flushInterval); } } async flush() { if (this.eventQueue.length === 0) return; const batch = this.eventQueue.splice(0, this.config.batchSize || 100); try { await this.sendBatch(batch); this.stats.eventsSent += batch.length; this.stats.eventsQueued = this.eventQueue.length; } catch (error) { // Re-queue failed events this.eventQueue.unshift(...batch); this.stats.eventsQueued = this.eventQueue.length; throw error; } } shouldFilter(event) { if (!this.config.filters) return false; for (const filter of this.config.filters) { const fieldValue = event[filter.field]; let matches = false; switch (filter.operator) { case 'equals': matches = fieldValue === filter.value; break; case 'contains': matches = String(fieldValue).includes(filter.value); break; case 'startsWith': matches = String(fieldValue).startsWith(filter.value); break; case 'endsWith': matches = String(fieldValue).endsWith(filter.value); break; case 'regex': matches = new RegExp(filter.value).test(String(fieldValue)); break; case 'in': matches = filter.value.includes(fieldValue); break; case 'notIn': matches = !filter.value.includes(fieldValue); break; } if (filter.action === 'exclude' && matches) return true; if (filter.action === 'include' && !matches) return true; } return false; } transformEvent(event) { if (!this.config.transformation) return event; const transform = this.config.transformation; let transformed = event; // Apply custom transformer if (transform.customTransformer) { transformed = transform.customTransformer(event); } // Apply field mapping if (transform.fieldMapping) { const mapped = {}; for (const [from, to] of Object.entries(transform.fieldMapping)) { if (from in transformed) { mapped[to] = transformed[from]; } } transformed = { ...transformed, ...mapped }; } // Apply enrichment if (transform.enrichment) { for (const enrichment of transform.enrichment) { let value; switch (enrichment.source) { case 'ENV': value = process.env[enrichment.value]; break; case 'CONFIG': value = enrichment.value; break; case 'FUNCTION': value = enrichment.value(event); break; } transformed[enrichment.field] = value; } } // Format transformation switch (transform.format) { case 'CEF': return this.formatCEF(transformed); case 'LEEF': return this.formatLEEF(transformed); case 'SYSLOG': return this.formatSyslog(transformed); case 'JSON': default: return transformed; } } formatCEF(event) { const header = `CEF:${event.version}|${event.deviceVendor}|${event.deviceProduct}|${event.deviceVersion}|${event.signatureId}|${event.name}|${event.severity}`; const extensions = Object.entries(event) .filter(([key]) => !['version', 'deviceVendor', 'deviceProduct', 'deviceVersion', 'signatureId', 'name', 'severity'].includes(key)) .map(([key, value]) => `${key}=${value}`) .join(' '); return `${header}|${extensions}`; } formatLEEF(event) { const header = `LEEF:2.0|${event.deviceVendor}|${event.deviceProduct}|${event.deviceVersion}|${event.signatureId}`; const attributes = Object.entries(event) .filter(([key]) => !['deviceVendor', 'deviceProduct', 'deviceVersion', 'signatureId'].includes(key)) .map(([key, value]) => `${key}=${value}`) .join('\t'); return `${header}|${attributes}`; } formatSyslog(event) { const priority = event.severity * 8 + 6; // Default facility 6 (local use) const timestamp = event.timestamp.toISOString(); const hostname = process.env.HOSTNAME || 'localhost'; const tag = `${event.deviceProduct}[${process.pid}]`; return `<${priority}>${timestamp} ${hostname} ${tag}: ${event.message}`; } handleError(error) { this.stats.errors++; this.stats.lastError = error.message; this.emit('error', error); } async dispose() { if (this.batchTimer) { clearInterval(this.batchTimer); } await this.flush(); await this.disconnect(); } } /** * Splunk SIEM Connector */ class SplunkConnector extends BaseSIEMConnector { get platform() { return types_1.SIEMPlatform.SPLUNK; } async connect() { // In production, would establish connection to Splunk HEC this.connected = true; this.stats.lastConnected = new Date(); this.emit('connected', { platform: this.platform }); } async disconnect() { // In production, would close Splunk connection this.connected = false; this.emit('disconnected', { platform: this.platform }); } async sendBatch(events) { if (!this.connected) await this.connect(); // Transform events for Splunk const splunkEvents = events.map(event => ({ time: event.timestamp.getTime() / 1000, host: event.sourceAddress || process.env.HOSTNAME, source: event.deviceProduct, sourcetype: '_json', event: this.transformEvent(event) })); // In production, would send to Splunk HEC endpoint // For now, simulate sending await new Promise(resolve => setTimeout(resolve, 10)); this.emit('events:sent', { count: events.length, platform: this.platform }); } async query(query) { if (!this.connected) await this.connect(); // In production, would execute Splunk search // For now, return mock results return { total: 0, events: [] }; } } /** * Elastic SIEM Connector */ class ElasticConnector extends BaseSIEMConnector { get platform() { return types_1.SIEMPlatform.ELASTIC; } async connect() { // In production, would establish connection to Elasticsearch this.connected = true; this.stats.lastConnected = new Date(); this.emit('connected', { platform: this.platform }); } async disconnect() { // In production, would close Elasticsearch connection this.connected = false; this.emit('disconnected', { platform: this.platform }); } async sendBatch(events) { if (!this.connected) await this.connect(); // Transform events for Elastic Common Schema (ECS) const ecsEvents = events.map(event => ({ '@timestamp': event.timestamp, ecs: { version: '1.12.0' }, event: { kind: 'event', category: event.eventType.toLowerCase(), type: [event.eventType.toLowerCase()], outcome: event.outcome?.toLowerCase(), severity: event.severity }, source: { ip: event.sourceAddress, port: event.sourcePort, user: { name: event.sourceUserName } }, destination: { ip: event.destinationAddress, port: event.destinationPort, user: { name: event.destinationUserName } }, user: { id: event.userId, name: event.userName }, message: event.message, labels: event.customFields })); // In production, would bulk index to Elasticsearch await new Promise(resolve => setTimeout(resolve, 10)); this.emit('events:sent', { count: events.length, platform: this.platform }); } async query(query) { if (!this.connected) await this.connect(); // In production, would execute Elasticsearch query return { total: 0, events: [] }; } } /** * IBM QRadar Connector */ class QRadarConnector extends BaseSIEMConnector { get platform() { return types_1.SIEMPlatform.QRADAR; } async connect() { // In production, would establish connection to QRadar this.connected = true; this.stats.lastConnected = new Date(); this.emit('connected', { platform: this.platform }); } async disconnect() { this.connected = false; this.emit('disconnected', { platform: this.platform }); } async sendBatch(events) { if (!this.connected) await this.connect(); // Transform events for QRadar LEEF format const leefEvents = events.map(event => this.formatLEEF(event)); // In production, would send to QRadar syslog endpoint await new Promise(resolve => setTimeout(resolve, 10)); this.emit('events:sent', { count: events.length, platform: this.platform }); } async query(query) { if (!this.connected) await this.connect(); // In production, would execute AQL query return { total: 0, events: [] }; } } /** * Azure Sentinel Connector */ class SentinelConnector extends BaseSIEMConnector { get platform() { return types_1.SIEMPlatform.SENTINEL; } async connect() { // In production, would authenticate with Azure this.connected = true; this.stats.lastConnected = new Date(); this.emit('connected', { platform: this.platform }); } async disconnect() { this.connected = false; this.emit('disconnected', { platform: this.platform }); } async sendBatch(events) { if (!this.connected) await this.connect(); // Transform events for Azure Sentinel const sentinelEvents = events.map(event => ({ TimeGenerated: event.timestamp, EventType: event.eventType, Severity: this.mapSeverityToSentinel(event.severity), Computer: event.sourceAddress || process.env.HOSTNAME, UserName: event.userName, Message: event.message, ...event.customFields })); // In production, would send to Log Analytics Data Collector API await new Promise(resolve => setTimeout(resolve, 10)); this.emit('events:sent', { count: events.length, platform: this.platform }); } async query(query) { if (!this.connected) await this.connect(); // In production, would execute KQL query return { total: 0, events: [] }; } mapSeverityToSentinel(severity) { const mapping = { [types_1.SIEMSeverity.EMERGENCY]: 'High', [types_1.SIEMSeverity.ALERT]: 'High', [types_1.SIEMSeverity.CRITICAL]: 'High', [types_1.SIEMSeverity.ERROR]: 'Medium', [types_1.SIEMSeverity.WARNING]: 'Medium', [types_1.SIEMSeverity.NOTICE]: 'Low', [types_1.SIEMSeverity.INFORMATIONAL]: 'Informational', [types_1.SIEMSeverity.DEBUG]: 'Informational' }; return mapping[severity] || 'Informational'; } } /** * SIEM Connector Factory */ class SIEMConnectorFactory { /** * Create a SIEM connector */ static create(config) { const key = `${config.platform}-${config.endpoint}`; // Return existing connector if available if (this.connectors.has(key)) { return this.connectors.get(key); } let connector; switch (config.platform) { case types_1.SIEMPlatform.SPLUNK: connector = new SplunkConnector(config); break; case types_1.SIEMPlatform.ELASTIC: connector = new ElasticConnector(config); break; case types_1.SIEMPlatform.QRADAR: connector = new QRadarConnector(config); break; case types_1.SIEMPlatform.SENTINEL: connector = new SentinelConnector(config); break; default: throw new Error(`Unsupported SIEM platform: ${config.platform}`); } this.connectors.set(key, connector); return connector; } /** * Get all active connectors */ static getConnectors() { return Array.from(this.connectors.values()); } /** * Dispose all connectors */ static async disposeAll() { const connectors = Array.from(this.connectors.values()); await Promise.all(connectors.map(c => c.dispose())); this.connectors.clear(); } } exports.SIEMConnectorFactory = SIEMConnectorFactory; SIEMConnectorFactory.connectors = new Map(); //# sourceMappingURL=siem-connector-factory.js.map