{"version":3,"sources":["/home/x/core/projects/battle/dist/chunk-YN6PSCTM.cjs","../src/security/SafeCommandMode.ts","../src/security/index.ts"],"names":["SecurityLevel"],"mappings":"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","file":"/home/x/core/projects/battle/dist/chunk-YN6PSCTM.cjs","sourcesContent":[null,"/**\n * Safe Command Mode - Flexible security for Battle Framework\n * Allows legitimate complex commands while blocking malicious ones\n */\n\nimport { CommandSanitizer } from './index.js'\n\nexport enum SecurityLevel {\n    STRICT = 'strict',        // Block all shell metacharacters\n    BALANCED = 'balanced',    // Allow safe patterns, block dangerous ones\n    PERMISSIVE = 'permissive' // Allow most things, block only obvious attacks\n}\n\nexport class SafeCommandMode {\n    \n    /**\n     * Validates commands based on security level and use case\n     */\n    static validateCommand(\n        command: string, \n        level: SecurityLevel = SecurityLevel.BALANCED,\n        context?: string\n    ): { valid: boolean; sanitized?: string; error?: string } {\n        \n        // Always block obvious attacks\n        const dangerousPatterns = [\n            /rm\\s+-rf\\s+[\\/~]/,           // Dangerous file deletion\n            /:\\(\\)\\{.*\\}:/,               // Fork bomb\n            /curl.*\\|\\s*sh/,              // Remote code execution\n            /wget.*\\|\\s*sh/,              // Remote code execution\n            /eval\\s*\\(/,                  // Code evaluation\n            /exec\\s*\\(/,                  // Code execution\n            /system\\s*\\(/,                // System calls\n        ]\n        \n        for (const pattern of dangerousPatterns) {\n            if (pattern.test(command)) {\n                return { \n                    valid: false, \n                    error: `Blocked dangerous pattern: ${pattern}` \n                }\n            }\n        }\n        \n        switch (level) {\n            case SecurityLevel.STRICT:\n                return this.validateStrict(command)\n                \n            case SecurityLevel.BALANCED:\n                return this.validateBalanced(command)\n                \n            case SecurityLevel.PERMISSIVE:\n                return this.validatePermissive(command)\n        }\n    }\n    \n    /**\n     * STRICT mode - Block all shell metacharacters\n     * Good for: Public APIs, untrusted input\n     */\n    private static validateStrict(command: string): { valid: boolean; error?: string } {\n        return CommandSanitizer.validate(command)\n    }\n    \n    /**\n     * BALANCED mode - Allow legitimate use cases\n     * Good for: Testing interactive applications, scripting\n     */\n    private static validateBalanced(command: string): { valid: boolean; sanitized?: string; error?: string } {\n        // Allow legitimate patterns\n        const safePatterns = [\n            // Interactive applications\n            /^[a-zA-Z0-9_\\-\\.\\/]+\\s+--interactive/,\n            /^[a-zA-Z0-9_\\-\\.\\/]+\\s+-i/,\n            \n            // Common testing patterns\n            /^echo\\s+[\\w\\s\\-\\.\\=]+$/,\n            /^cat\\s+[a-zA-Z0-9_\\-\\.\\/]+$/,\n            /^ls\\s+[a-zA-Z0-9_\\-\\.\\/\\s]*$/,\n            /^pwd$/,\n            /^whoami$/,\n            /^date$/,\n            \n            // Development tools\n            /^npm\\s+(install|test|run|start|build)(\\s+[a-zA-Z0-9_\\-]+)?$/,\n            /^git\\s+(status|log|diff|add|commit)(\\s+[a-zA-Z0-9_\\-\\.\\/\\s]*)?$/,\n            /^node\\s+[a-zA-Z0-9_\\-\\.\\/]+$/,\n            /^python3?\\s+[a-zA-Z0-9_\\-\\.\\/]+$/,\n            \n            // Interactive programs with input\n            /^[a-zA-Z0-9_\\-\\.\\/]+(\\s+[a-zA-Z0-9_\\-\\.=:\\/\\s]+)*$/\n        ]\n        \n        // Check if command matches safe patterns\n        for (const pattern of safePatterns) {\n            if (pattern.test(command)) {\n                return { valid: true, sanitized: command }\n            }\n        }\n        \n        // Check for dangerous combinations\n        const moderatelyDangerous = [\n            /;.*rm/,                      // Command chaining with rm\n            /\\|\\s*rm/,                    // Piping to rm\n            /&&.*rm/,                     // AND chaining with rm\n            // Allow stderr redirections (2>/dev/null) which are common for suppressing errors\n        ]\n        \n        for (const pattern of moderatelyDangerous) {\n            if (pattern.test(command)) {\n                return { \n                    valid: false, \n                    error: `Potentially dangerous pattern: ${pattern}` \n                }\n            }\n        }\n        \n        // Allow if not explicitly dangerous\n        return { valid: true, sanitized: command }\n    }\n    \n    /**\n     * PERMISSIVE mode - Allow most legitimate uses\n     * Good for: Internal tools, development, advanced users\n     */\n    private static validatePermissive(command: string): { valid: boolean; sanitized?: string; error?: string } {\n        // Only block the most obvious attacks\n        const criticalPatterns = [\n            /:\\(\\)\\{.*\\}:/,               // Fork bomb\n            /rm\\s+-rf\\s+\\/[^a-zA-Z]/,     // Root filesystem deletion\n            /chmod\\s+777\\s+\\/etc/,        // Critical permission changes\n            /\\/etc\\/passwd/,              // System file access\n            /\\/etc\\/shadow/,              // Password file access\n        ]\n        \n        for (const pattern of criticalPatterns) {\n            if (pattern.test(command)) {\n                return { \n                    valid: false, \n                    error: `Critical security violation: ${pattern}` \n                }\n            }\n        }\n        \n        return { valid: true, sanitized: command }\n    }\n    \n    /**\n     * Creates a safe command execution context\n     */\n    static createSafeContext(level: SecurityLevel): SafeCommandContext {\n        return new SafeCommandContext(level)\n    }\n}\n\n/**\n * Safe command execution context\n */\nexport class SafeCommandContext {\n    private level: SecurityLevel\n    private executedCommands: string[] = []\n    \n    constructor(level: SecurityLevel) {\n        this.level = level\n    }\n    \n    /**\n     * Validates and executes a command safely\n     */\n    validateAndExecute(command: string, args?: string[]): { valid: boolean; fullCommand?: string; error?: string } {\n        const fullCommand = args ? `${command} ${args.join(' ')}` : command\n        \n        const validation = SafeCommandMode.validateCommand(fullCommand, this.level)\n        \n        if (validation.valid) {\n            this.executedCommands.push(fullCommand)\n        }\n        \n        return {\n            valid: validation.valid,\n            fullCommand: validation.sanitized || fullCommand,\n            error: validation.error\n        }\n    }\n    \n    /**\n     * Gets execution history\n     */\n    getHistory(): string[] {\n        return [...this.executedCommands]\n    }\n    \n    /**\n     * Clears execution history\n     */\n    clearHistory(): void {\n        this.executedCommands = []\n    }\n}\n\nexport default SafeCommandMode","/**\n * Security utilities for Battle Framework\n * Provides comprehensive input validation, sanitization, and security measures\n */\n\nimport * as path from 'path'\nimport * as crypto from 'crypto'\n\n/**\n * Validates and sanitizes command input to prevent injection attacks\n */\nexport class CommandSanitizer {\n    private static readonly ALLOWED_CHARS = /^[a-zA-Z0-9\\s\\-_.\\/\\[\\]{}()=,:\"']+$/\n    private static readonly DANGEROUS_PATTERNS = [\n        /[;&|`$<>]/,  // Shell metacharacters\n        /\\.\\.\\//,      // Path traversal\n        /\\$\\(/,        // Command substitution\n        /\\|\\|/,        // OR operator\n        /&&/,          // AND operator\n    ]\n    \n    /**\n     * Validates if a command is safe to execute\n     */\n    static validate(command: string): { valid: boolean; error?: string } {\n        if (!command || typeof command !== 'string') {\n            return { valid: false, error: 'Command must be a non-empty string' }\n        }\n        \n        // Check length limits\n        if (command.length > 1000) {\n            return { valid: false, error: 'Command exceeds maximum length' }\n        }\n        \n        // Check for dangerous patterns\n        for (const pattern of this.DANGEROUS_PATTERNS) {\n            if (pattern.test(command)) {\n                return { valid: false, error: `Dangerous pattern detected: ${pattern}` }\n            }\n        }\n        \n        return { valid: true }\n    }\n    \n    /**\n     * Sanitizes command arguments\n     */\n    static sanitizeArgs(args: string[]): string[] {\n        return args.map(arg => {\n            // Remove any shell metacharacters\n            return arg.replace(/[;&|`$<>\\\\]/g, '')\n                     .replace(/\\.\\.\\//g, '')\n                     .slice(0, 500) // Limit arg length\n        })\n    }\n    \n    /**\n     * Escapes shell arguments properly\n     */\n    static escapeShellArg(arg: string): string {\n        return `'${arg.replace(/'/g, \"'\\\\''\")}'`\n    }\n}\n\n/**\n * Environment variable sanitizer\n */\nexport class EnvSanitizer {\n    private static readonly BLOCKED_VARS = [\n        'LD_PRELOAD',\n        'LD_LIBRARY_PATH',\n        'DYLD_INSERT_LIBRARIES',\n        'DYLD_LIBRARY_PATH',\n        'NODE_OPTIONS',\n        'NODE_EXTRA_CA_CERTS',\n    ]\n    \n    private static readonly SENSITIVE_PATTERNS = [\n        /^(PASSWORD|TOKEN|KEY|SECRET|API|PRIVATE|CREDENTIAL)/i,\n        /_KEY$/i,\n        /_TOKEN$/i,\n        /_SECRET$/i,\n    ]\n    \n    /**\n     * Sanitizes environment variables\n     */\n    static sanitize(env: Record<string, any>): Record<string, string> {\n        const sanitized: Record<string, string> = {}\n        \n        for (const [key, value] of Object.entries(env)) {\n            // Skip blocked variables\n            if (this.BLOCKED_VARS.includes(key)) {\n                continue\n            }\n            \n            // Mask sensitive variables\n            if (this.SENSITIVE_PATTERNS.some(pattern => pattern.test(key))) {\n                sanitized[key] = '***REDACTED***'\n                continue\n            }\n            \n            // Ensure value is a string and limit length\n            sanitized[key] = String(value).slice(0, 10000)\n        }\n        \n        return sanitized\n    }\n    \n    /**\n     * Creates safe environment for PTY\n     */\n    static createSafeEnv(userEnv: Record<string, any> = {}): Record<string, string> {\n        const baseEnv = {\n            TERM: 'xterm-256color',\n            LANG: 'en_US.UTF-8',\n            LC_ALL: 'en_US.UTF-8',\n            PATH: process.env.PATH || '/usr/bin:/bin',\n        }\n        \n        const sanitizedUserEnv = this.sanitize(userEnv)\n        return { ...baseEnv, ...sanitizedUserEnv }\n    }\n}\n\n/**\n * JSON Schema validator for replay files\n */\nexport class ReplayValidator {\n    private static readonly SCHEMA = {\n        version: 'string',\n        timestamp: 'string',\n        duration: 'number',\n        events: 'array',\n        metadata: 'object',\n    }\n    \n    /**\n     * Validates replay data structure\n     */\n    static validate(data: any): { valid: boolean; error?: string } {\n        if (!data || typeof data !== 'object') {\n            return { valid: false, error: 'Invalid replay data structure' }\n        }\n        \n        // Check required fields\n        for (const [field, type] of Object.entries(this.SCHEMA)) {\n            if (!(field in data)) {\n                return { valid: false, error: `Missing required field: ${field}` }\n            }\n            \n            const actualType = Array.isArray(data[field]) ? 'array' : typeof data[field]\n            if (actualType !== type) {\n                return { valid: false, error: `Invalid type for ${field}: expected ${type}, got ${actualType}` }\n            }\n        }\n        \n        // Validate events\n        if (!Array.isArray(data.events)) {\n            return { valid: false, error: 'Events must be an array' }\n        }\n        \n        for (const event of data.events) {\n            if (!event.type || typeof event.timestamp !== 'number') {\n                return { valid: false, error: 'Invalid event structure' }\n            }\n            // Some event types like 'exit' may not have data field\n        }\n        \n        return { valid: true }\n    }\n    \n    /**\n     * Safely parse JSON with validation\n     */\n    static parse(json: string): any {\n        try {\n            const data = JSON.parse(json, (key, value) => {\n                // Prevent prototype pollution\n                if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n                    return undefined\n                }\n                return value\n            })\n            \n            const validation = this.validate(data)\n            if (!validation.valid) {\n                throw new Error(validation.error)\n            }\n            \n            return data\n        } catch (error: any) {\n            if (error.message && error.message.includes('Invalid replay file:')) {\n                throw error; // Don't double-wrap already wrapped errors\n            }\n            throw new Error(`Invalid replay file: ${error}`)\n        }\n    }\n}\n\n/**\n * Path security utilities\n */\nexport class PathSecurity {\n    /**\n     * Validates and normalizes file paths\n     */\n    static validatePath(filePath: string, basePath: string): { valid: boolean; normalized?: string; error?: string } {\n        try {\n            const normalized = path.normalize(filePath)\n            const resolved = path.resolve(basePath, normalized)\n            \n            // Check for path traversal\n            if (!resolved.startsWith(path.resolve(basePath))) {\n                return { valid: false, error: 'Path traversal detected' }\n            }\n            \n            // Check for null bytes\n            if (filePath.includes('\\0')) {\n                return { valid: false, error: 'Null byte detected in path' }\n            }\n            \n            return { valid: true, normalized: resolved }\n        } catch (error) {\n            return { valid: false, error: `Invalid path: ${error}` }\n        }\n    }\n    \n    /**\n     * Creates safe temporary directory\n     */\n    static createSafeTempDir(): string {\n        const tempDir = path.join(process.cwd(), 'tmp', crypto.randomBytes(16).toString('hex'))\n        return tempDir\n    }\n}\n\n/**\n * Resource limiter to prevent DoS\n */\nexport class ResourceLimiter {\n    private static readonly MAX_OUTPUT_SIZE = 10 * 1024 * 1024 // 10MB\n    private static readonly MAX_EVENTS = 100000\n    private static readonly MAX_PTY_INSTANCES = 10\n    \n    private static ptyInstances = 0\n    \n    /**\n     * Checks if resource limit is exceeded\n     */\n    static checkOutputSize(size: number): boolean {\n        return size < this.MAX_OUTPUT_SIZE\n    }\n    \n    /**\n     * Checks if event count limit is exceeded\n     */\n    static checkEventCount(count: number): boolean {\n        return count < this.MAX_EVENTS\n    }\n    \n    /**\n     * Tracks PTY instance creation\n     */\n    static acquirePTY(): boolean {\n        if (this.ptyInstances >= this.MAX_PTY_INSTANCES) {\n            return false\n        }\n        this.ptyInstances++\n        return true\n    }\n    \n    /**\n     * Releases PTY instance\n     */\n    static releasePTY(): void {\n        if (this.ptyInstances > 0) {\n            this.ptyInstances--\n        }\n    }\n}\n\n/**\n * Secure error handler that prevents information disclosure\n */\nexport class SecureErrorHandler {\n    private static readonly ERROR_MAP = new Map([\n        ['ENOENT', 'Resource not found'],\n        ['EACCES', 'Permission denied'],\n        ['EAGAIN', 'Resource temporarily unavailable'],\n        ['EBADF', 'Invalid resource reference'],\n        ['EIO', 'I/O error occurred'],\n    ])\n    \n    /**\n     * Sanitizes error messages to prevent information disclosure\n     */\n    static sanitize(error: any): string {\n        if (!error) return 'Unknown error'\n        \n        const code = error.code || error.errno\n        if (code && this.ERROR_MAP.has(code)) {\n            return this.ERROR_MAP.get(code)!\n        }\n        \n        // Remove sensitive information from error messages\n        let message = String(error.message || error)\n        \n        // Remove file paths\n        message = message.replace(/\\/[^\\s]+/g, '<path>')\n        \n        // Remove IP addresses\n        message = message.replace(/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/g, '<ip>')\n        \n        // Remove ports\n        message = message.replace(/:\\d{2,5}/g, ':<port>')\n        \n        // Limit message length\n        return message.slice(0, 200)\n    }\n    \n    /**\n     * Logs error securely\n     */\n    static log(error: any, context?: string): void {\n        const sanitized = this.sanitize(error)\n        const timestamp = new Date().toISOString()\n        \n        console.error(`[${timestamp}] ${context || 'Error'}: ${sanitized}`)\n        \n        // In production, would send to secure logging service\n    }\n}\n\nexport { SafeCommandMode, SecurityLevel, SafeCommandContext } from './SafeCommandMode.js'\n\nexport default {\n    CommandSanitizer,\n    EnvSanitizer,\n    ReplayValidator,\n    PathSecurity,\n    ResourceLimiter,\n    SecureErrorHandler,\n}"]}