Spaces:
Paused
Paused
| // 🛡️ 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: /<script\b[^>]*>/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<string>(); | |
| 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<string, { count: number; resetTime: number }>(); | |
| 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; | |