UNPKG

@iota-big3/sdk-security

Version:

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

314 lines 10.9 kB
"use strict"; /** * @iota-big3/sdk-security - Security Scanner * SAST, DAST, SCA and other security scanning capabilities */ Object.defineProperty(exports, "__esModule", { value: true }); exports.SecurityScanner = void 0; const events_1 = require("events"); class SecurityScanner extends events_1.EventEmitter { constructor(config, logger) { super(); this.isEnabled = true; this.scans = []; this.schedules = new Map(); this.customScanners = new Map(); this.isInitialized = false; this.config = config; this.logger = logger; this.enabledScanners = new Set(config.enabledScanners); } async initialize() { if (this.isInitialized) { return; } try { this.logger.info('Initializing security scanner'); // Initialize scanning engines await this.initializeScanners(); this.isInitialized = true; this.emit('scanner:initialized'); } catch (error) { this.logger.error('Failed to initialize security scanner', error); this.emit('scanner:error', error); throw error; } } async initializeScanners() { // Initialize each scanner type for (const scanner of this.enabledScanners) { this.logger.debug(`Initializing ${scanner} scanner`); } } async startScan(type, target, context) { const scan = { id: this.generateScanId(), type, target, context, status: 'running', startTime: new Date(), findings: [], summary: { totalFindings: 0, criticalCount: 0, highCount: 0, mediumCount: 0, lowCount: 0 } }; this.scans.push(scan); this.emit('scan:started', scan); // Simulate async scanning setTimeout(async () => { try { const findings = await this.performScan(type, target, context); scan.findings = findings; scan.status = 'completed'; scan.endTime = new Date(); scan.summary = this.calculateSummary(findings); this.emit('scan:completed', scan); } catch (error) { scan.status = 'failed'; scan.endTime = new Date(); this.emit('scan:failed', scan, error); } }, 50); // Simulate scan time return scan.id; } async performScan(type, target, context) { const findings = []; // Use custom scanner if available if (this.customScanners.has(type)) { const scanner = this.customScanners.get(type); const result = await scanner.scan(target, context); return result.findings; } // Mock findings for demonstration if (type === 'SAST') { findings.push({ id: `finding-${Date.now()}-1`, type: 'SQL_INJECTION', severity: 'HIGH', title: 'Potential SQL Injection', description: 'User input not properly sanitized', recommendation: 'Use parameterized queries', cve: 'CWE-89' }); } else if (type === 'SCA') { findings.push({ id: `finding-${Date.now()}-2`, type: 'VULNERABLE_DEPENDENCY', severity: 'CRITICAL', title: 'Vulnerable dependency detected', description: 'lodash@4.17.19 has known vulnerabilities', recommendation: 'Update to lodash@4.17.21', cve: 'CVE-2021-23337', cvssScore: 7.2 }); } return findings; } async runFullScan(target) { const results = new Map(); for (const scanType of this.enabledScanners) { const scanId = await this.startScan(scanType, target, 'full-scan'); // Wait for scan to complete await new Promise(resolve => { const checkInterval = setInterval(() => { const scan = this.scans.find(s => s.id === scanId); if (scan && scan.status !== 'running') { clearInterval(checkInterval); results.set(scanType, { findings: scan.findings, summary: scan.summary }); resolve(undefined); } }, 10); }); } return results; } getFindings(options) { const allFindings = this.scans.flatMap(scan => scan.findings); if (options?.severityThreshold) { const severityOrder = { 'critical': 4, 'high': 3, 'medium': 2, 'low': 1 }; const threshold = severityOrder[options.severityThreshold.toLowerCase()] || 0; return allFindings.filter(finding => { const findingSeverity = severityOrder[finding.severity.toLowerCase()] || 0; return findingSeverity >= threshold; }); } return allFindings; } getScans() { return this.scans; } getEnabledScanners() { return Array.from(this.enabledScanners); } enableScanner(type) { this.enabledScanners.add(type); } disableScanner(type) { this.enabledScanners.delete(type); } addCustomScanner(type, scanner) { this.customScanners.set(type, scanner); this.emit('scanner:added', type); } exportResults(scan, format) { switch (format) { case 'sarif': return this.exportSARIF(scan); case 'json': return this.exportJSON(scan); case 'csv': return this.exportCSV(scan); default: return this.exportJSON(scan); } } exportSARIF(scan) { const sarif = { version: '2.1.0', runs: [{ tool: { driver: { name: `IotaSDK ${scan.type} Scanner`, version: '2.0.0' } }, results: scan.findings.map(finding => ({ ruleId: finding.type, level: this.severityToSarifLevel(finding.severity), message: { text: finding.description }, fixes: finding.recommendation ? [{ description: { text: finding.recommendation } }] : undefined })) }] }; return JSON.stringify(sarif, null, 2); } exportJSON(scan) { return JSON.stringify({ scan: { id: scan.id, type: scan.type, target: scan.target, startTime: scan.startTime, endTime: scan.endTime, status: scan.status }, findings: scan.findings, summary: scan.summary }, null, 2); } exportCSV(scan) { const headers = 'severity,type,file,line,message,recommendation,cve\n'; const rows = scan.findings.map(finding => `${finding.severity},${finding.type},"${scan.target}",0,"${finding.description}","${finding.recommendation || ''}","${finding.cve || ''}"`).join('\n'); return headers + rows; } scheduleScan(schedule) { const scheduleId = this.generateScheduleId(); const scanSchedule = { id: scheduleId, type: schedule.type, target: schedule.target, schedule: schedule.schedule }; this.schedules.set(scheduleId, scanSchedule); this.emit('scan:scheduled', scanSchedule); return scheduleId; } cancelScheduledScan(scheduleId) { if (this.schedules.delete(scheduleId)) { this.emit('scan:cancelled', scheduleId); } } getStats() { const activeScans = this.scans.filter(s => s.status === 'running').length; const totalFindings = this.scans.reduce((sum, scan) => sum + scan.findings.length, 0); return { isInitialized: this.isInitialized, totalScans: this.scans.length, activeScans, enabledScanners: Array.from(this.enabledScanners), findingsCount: totalFindings, schedules: this.schedules.size, config: { severityThreshold: this.config.severityThreshold, scheduledScans: this.config.scheduledScans, scanOnCommit: this.config.scanOnCommit } }; } async shutdown() { if (!this.isInitialized) { return; } try { this.schedules.clear(); this.scans = []; this.customScanners.clear(); this.isInitialized = false; this.emit('scanner:shutdown'); } catch (error) { this.logger.error('Error during scanner shutdown', error); throw error; } } generateScanId() { return `scan-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; } generateScheduleId() { return `schedule-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; } calculateSummary(findings) { const summary = { totalFindings: findings.length, criticalCount: 0, highCount: 0, mediumCount: 0, lowCount: 0 }; for (const finding of findings) { switch (finding.severity.toUpperCase()) { case 'CRITICAL': summary.criticalCount++; break; case 'HIGH': summary.highCount++; break; case 'MEDIUM': summary.mediumCount++; break; case 'LOW': summary.lowCount++; break; } } return summary; } severityToSarifLevel(severity) { const mapping = { 'CRITICAL': 'error', 'HIGH': 'error', 'MEDIUM': 'warning', 'LOW': 'note' }; return mapping[severity.toUpperCase()] || 'note'; } } exports.SecurityScanner = SecurityScanner; //# sourceMappingURL=security-scanner.js.map