UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

297 lines (261 loc) • 6.92 kB
/** * Security Domain Service - Domain Layer * * Contains security logic for validation, policy enforcement, and threat detection. * * @module v3/security/domain/services */ import { SecurityContext, PermissionLevel } from '../entities/security-context.js'; /** * Validation result */ export interface ValidationResult { valid: boolean; errors: string[]; warnings: string[]; sanitized?: string; } /** * Threat detection result */ export interface ThreatDetectionResult { safe: boolean; threats: Array<{ type: string; severity: 'low' | 'medium' | 'high' | 'critical'; description: string; location?: string; }>; } /** * Security Domain Service */ export class SecurityDomainService { // Dangerous patterns for path traversal private static readonly PATH_TRAVERSAL_PATTERNS = [ /\.\./, /~\//, /^\/etc\//, /^\/tmp\//, /^\/var\/log\//, /^C:\\Windows/i, /^C:\\Users\\[^\\]+\\AppData/i, ]; // Dangerous command patterns private static readonly DANGEROUS_COMMANDS = [ /^rm\s+-rf\s+\//, /^rm\s+-rf\s+\*/, /^dd\s+if=/, /^mkfs\./, /^format\s+/i, /^del\s+\/s\s+\/q/i, />\s*\/dev\/sd[a-z]/, /\|\s*bash$/, /\|\s*sh$/, /eval\s*\(/, /exec\s*\(/, ]; // SQL injection patterns private static readonly SQL_INJECTION_PATTERNS = [ /'\s*OR\s+'1'\s*=\s*'1/i, /'\s*OR\s+1\s*=\s*1/i, /;\s*DROP\s+TABLE/i, /;\s*DELETE\s+FROM/i, /UNION\s+SELECT/i, /--\s*$/, ]; // XSS patterns private static readonly XSS_PATTERNS = [ /<script[\s>]/i, /javascript:/i, /on\w+\s*=/i, /<iframe/i, /<object/i, /<embed/i, ]; /** * Validate a file path */ validatePath(path: string, context: SecurityContext): ValidationResult { const errors: string[] = []; const warnings: string[] = []; // Check path traversal for (const pattern of SecurityDomainService.PATH_TRAVERSAL_PATTERNS) { if (pattern.test(path)) { errors.push(`Path traversal detected: ${pattern.source}`); } } // Check context permissions if (!context.canAccessPath(path)) { errors.push(`Access denied to path: ${path}`); } // Check for suspicious paths if (path.includes('..')) { warnings.push('Path contains parent directory reference'); } return { valid: errors.length === 0, errors, warnings, sanitized: this.sanitizePath(path), }; } /** * Validate a command */ validateCommand(command: string, context: SecurityContext): ValidationResult { const errors: string[] = []; const warnings: string[] = []; // Check dangerous commands for (const pattern of SecurityDomainService.DANGEROUS_COMMANDS) { if (pattern.test(command)) { errors.push(`Dangerous command pattern detected: ${pattern.source}`); } } // Check context permissions if (!context.canExecuteCommand(command)) { errors.push(`Command execution denied: ${command}`); } if (!context.hasPermission('execute')) { errors.push('Execute permission required'); } // Check for shell injection if (/[;&|`$(){}]/.test(command)) { warnings.push('Command contains shell metacharacters'); } return { valid: errors.length === 0, errors, warnings, sanitized: this.sanitizeCommand(command), }; } /** * Validate user input */ validateInput(input: string): ValidationResult { const errors: string[] = []; const warnings: string[] = []; // Check for SQL injection for (const pattern of SecurityDomainService.SQL_INJECTION_PATTERNS) { if (pattern.test(input)) { errors.push(`SQL injection pattern detected`); break; } } // Check for XSS for (const pattern of SecurityDomainService.XSS_PATTERNS) { if (pattern.test(input)) { errors.push(`XSS pattern detected`); break; } } // Check length if (input.length > 10000) { warnings.push('Input exceeds recommended length'); } return { valid: errors.length === 0, errors, warnings, sanitized: this.sanitizeInput(input), }; } /** * Detect threats in content */ detectThreats(content: string): ThreatDetectionResult { const threats: ThreatDetectionResult['threats'] = []; // Check for various threat patterns if (/<script/i.test(content)) { threats.push({ type: 'xss', severity: 'high', description: 'Script tag detected', }); } if (/password\s*[:=]\s*["'][^"']+["']/i.test(content)) { threats.push({ type: 'credential-exposure', severity: 'critical', description: 'Hardcoded password detected', }); } if (/api[_-]?key\s*[:=]\s*["'][^"']+["']/i.test(content)) { threats.push({ type: 'credential-exposure', severity: 'critical', description: 'API key detected', }); } if (/eval\s*\(/.test(content)) { threats.push({ type: 'code-injection', severity: 'high', description: 'Eval statement detected', }); } return { safe: threats.length === 0, threats, }; } /** * Sanitize path */ private sanitizePath(path: string): string { return path .replace(/\.\./g, '') .replace(/\/\//g, '/') .replace(/^~\//, '') .trim(); } /** * Sanitize command */ private sanitizeCommand(command: string): string { return command .replace(/[;&|`$]/g, '') .replace(/\$\([^)]*\)/g, '') .trim(); } /** * Sanitize user input */ private sanitizeInput(input: string): string { return input .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&#x27;') .replace(/\//g, '&#x2F;'); } /** * Create security context for agent */ createAgentContext( agentId: string, role: string, customPaths?: string[] ): SecurityContext { // Default permissions based on role const rolePermissions: Record<string, PermissionLevel[]> = { 'queen-coordinator': ['read', 'write', 'execute', 'admin'], 'security-architect': ['read', 'write', 'execute', 'admin'], 'coder': ['read', 'write', 'execute'], 'reviewer': ['read'], 'tester': ['read', 'execute'], default: ['read'], }; const permissions = rolePermissions[role] ?? rolePermissions.default; return SecurityContext.create({ principalId: agentId, principalType: 'agent', permissions, allowedPaths: customPaths ?? ['./src', './tests', './docs'], blockedPaths: ['/etc', '/var', '~/', '../'], allowedCommands: ['npm', 'node', 'git', 'vitest'], blockedCommands: ['rm -rf /', 'dd', 'mkfs', 'format'], }); } }