// 🛡️ THE SHIELD: AngelProxy.ts // Point 5: Predictive Threat Anticipation // Point 10: Cosmic Context Augmentation // Patcher sikkerhedshuller før de findes. Augmenterer virkeligheden. import { Request, Response, NextFunction } from 'express'; // Conditional imports let metricsService: any = null; let neo4jService: any = null; // Initialize services (async () => { try { const metrics = await import('../services/MetricsService.js').catch(() => null); if (metrics) metricsService = metrics.metricsService; const neo4j = await import('../database/Neo4jService.js').catch(() => null); if (neo4j) neo4jService = neo4j.neo4jService; } catch { /* ignore */ } })(); interface ThreatPattern { pattern: string | RegExp; severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'; description: string; honeypot?: boolean; } // Known threat patterns const THREAT_PATTERNS: ThreatPattern[] = [ // SQL/Cypher Injection { pattern: /drop\s+(database|table|index)/i, severity: 'CRITICAL', description: 'Database destruction attempt', honeypot: true }, { pattern: /detach\s+delete/i, severity: 'CRITICAL', description: 'Neo4j graph deletion', honeypot: true }, { pattern: /truncate\s+table/i, severity: 'CRITICAL', description: 'Table truncation', honeypot: true }, { pattern: /;\s*delete\s+from/i, severity: 'HIGH', description: 'SQL injection deletion' }, // Command Injection { pattern: /rm\s+-rf/i, severity: 'CRITICAL', description: 'File system destruction', honeypot: true }, { pattern: /;\s*(bash|sh|cmd|powershell)/i, severity: 'HIGH', description: 'Shell injection' }, { pattern: /\|\s*(cat|type)\s+\/etc/i, severity: 'HIGH', description: 'System file access' }, // Path Traversal { pattern: /\.\.\//g, severity: 'MEDIUM', description: 'Path traversal attempt' }, { pattern: /%2e%2e%2f/gi, severity: 'MEDIUM', description: 'Encoded path traversal' }, // XSS Patterns { pattern: /]*>/i, severity: 'MEDIUM', description: 'XSS script injection' }, { pattern: /javascript:/i, severity: 'MEDIUM', description: 'JavaScript protocol' }, { pattern: /on\w+\s*=/i, severity: 'LOW', description: 'Event handler injection' }, // Sensitive Data Exfil { pattern: /password|secret|api.?key|bearer/i, severity: 'LOW', description: 'Sensitive keyword in payload' } ]; export class AngelProxy { private static blockedIPs = new Set(); private static requestLog: { ip: string; timestamp: number; threat?: string }[] = []; private static maxLogSize = 1000; /** * Point 5: Cortex Firewall * Scanner indgående trafik for mønstre, der matcher kendte sårbarheder */ public static async cortexFirewall(req: Request, res: Response, next: NextFunction) { const clientIP = req.ip || req.socket.remoteAddress || 'unknown'; // Check if IP is blocked if (AngelProxy.blockedIPs.has(clientIP)) { return AngelProxy.honeypotResponse(res, 'IP blocked'); } // Build payload string for analysis const payload = AngelProxy.buildPayloadString(req); // Scan for threats for (const threat of THREAT_PATTERNS) { const matched = typeof threat.pattern === 'string' ? payload.toLowerCase().includes(threat.pattern.toLowerCase()) : threat.pattern.test(payload); if (matched) { console.warn(`🛡️ [ANGEL] Threat Intercepted from ${clientIP}: ${threat.description}`); // Log threat AngelProxy.logRequest(clientIP, threat.description); // Increment metrics if (metricsService) { metricsService.incrementCounter('security_threat_blocked'); metricsService.incrementCounter(`security_threat_${threat.severity.toLowerCase()}`); } // Block IP on critical threats if (threat.severity === 'CRITICAL') { AngelProxy.blockedIPs.add(clientIP); console.warn(`🛡️ [ANGEL] IP Blocked: ${clientIP}`); } // Return honeypot response if (threat.honeypot) { return AngelProxy.honeypotResponse(res, threat.description); } // Otherwise reject return res.status(403).json({ error: 'Request blocked by security filter', code: 'THREAT_DETECTED' }); } } // Log clean request AngelProxy.logRequest(clientIP); next(); } /** * Honeypot Response: Pretend the attack succeeded */ private static honeypotResponse(res: Response, _threat: string) { return res.status(200).json({ success: true, message: 'Command executed successfully', data: null, timestamp: new Date().toISOString() }); } /** * Build payload string from request for analysis */ private static buildPayloadString(req: Request): string { const parts: string[] = []; if (req.body) parts.push(JSON.stringify(req.body)); if (req.query) parts.push(JSON.stringify(req.query)); if (req.params) parts.push(JSON.stringify(req.params)); parts.push(req.url); return parts.join(' '); } private static logRequest(ip: string, threat?: string) { AngelProxy.requestLog.push({ ip, timestamp: Date.now(), threat }); // Trim log if (AngelProxy.requestLog.length > AngelProxy.maxLogSize) { AngelProxy.requestLog = AngelProxy.requestLog.slice(-AngelProxy.maxLogSize); } } /** * Point 10: Cosmic Context Augmentation * Augment external content with internal knowledge */ public static async augmentReality(url: string): Promise<{ original: string; augmented: string; context: string[] }> { try { // Fetch external content const response = await fetch(url, { headers: { 'User-Agent': 'WidgeTDC-Angel/1.0' }, signal: AbortSignal.timeout(10000) }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const originalText = await response.text(); const contextBlocks: string[] = []; // Find internal knowledge related to this URL if (neo4jService) { try { const hostname = new URL(url).hostname; const internalData = await neo4jService.query(` MATCH (n:Knowledge) WHERE n.content CONTAINS $domain OR n.url CONTAINS $domain RETURN n.summary AS context LIMIT 3 `, { domain: hostname }); for (const record of internalData) { if (record.context) { contextBlocks.push(record.context); } } } catch { /* ignore neo4j errors */ } } const augmentedText = contextBlocks.length > 0 ? `[INTERNAL CONTEXT]\n${contextBlocks.join('\n')}\n[END CONTEXT]\n\n${originalText}` : originalText; return { original: originalText, augmented: augmentedText, context: contextBlocks }; } catch (error: any) { throw new Error(`Failed to augment URL: ${error.message}`); } } /** * Rate limiting middleware */ public static rateLimiter(maxRequests: number = 100, windowMs: number = 60000) { const requestCounts = new Map(); return (req: Request, res: Response, next: NextFunction) => { const clientIP = req.ip || 'unknown'; const now = Date.now(); let record = requestCounts.get(clientIP); if (!record || now > record.resetTime) { record = { count: 0, resetTime: now + windowMs }; requestCounts.set(clientIP, record); } record.count++; if (record.count > maxRequests) { console.warn(`🛡️ [ANGEL] Rate limit exceeded: ${clientIP}`); return res.status(429).json({ error: 'Too many requests', retryAfter: Math.ceil((record.resetTime - now) / 1000) }); } next(); }; } // Public getters for stats public static getStats() { const recentThreats = AngelProxy.requestLog.filter(r => r.threat); return { blockedIPs: AngelProxy.blockedIPs.size, recentRequests: AngelProxy.requestLog.length, recentThreats: recentThreats.length, threatBreakdown: THREAT_PATTERNS.map(t => t.description) }; } public static getBlockedIPs(): string[] { return Array.from(AngelProxy.blockedIPs); } public static unblockIP(ip: string): boolean { return AngelProxy.blockedIPs.delete(ip); } } export default AngelProxy;