UNPKG

@light-merlin-dark/vssh

Version:

MCP-native SSH proxy for AI agents. CLI & MCP Server, plugin system, AI safety guards.

127 lines 7.37 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.CommandGuard = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const config_1 = require("../config"); class CommandGuard { static checkCommand(command) { const reasons = []; let rule; // Check dangerous patterns for (const { pattern, reason } of this.DANGEROUS_PATTERNS) { if (pattern.test(command)) { reasons.push(reason); rule = pattern.toString(); break; } } // Check suspicious patterns for (const { pattern, reason } of this.SUSPICIOUS_PATTERNS) { if (pattern.test(command)) { reasons.push(`⚠️ WARNING: ${reason}`); if (!rule) rule = pattern.toString(); } } return { isBlocked: reasons.length > 0 && !reasons[0].startsWith('⚠️'), reasons, rule }; } static displayBlockedMessage(command, result) { console.error('\n🚫 COMMAND BLOCKED FOR SAFETY REASONS\n'); console.error(`Command: ${command}`); console.error(`Reason: ${result.reasons[0]}`); console.error('\nThis command has been blocked to prevent potential system damage.'); console.error('If you believe this is a false positive, please review the command carefully.\n'); } static logBlockedCommand(command, result) { const timestamp = new Date().toISOString(); const logEntry = `[${timestamp}] BLOCKED: ${command}\nReason: ${result.reasons.join(', ')}\nRule: ${result.rule}\n${'='.repeat(80)}\n`; const logPath = path.join(config_1.LOGS_PATH, 'blocked_commands.log'); fs.appendFileSync(logPath, logEntry); } } exports.CommandGuard = CommandGuard; CommandGuard.DANGEROUS_PATTERNS = [ // Filesystem destruction - Enhanced patterns { pattern: /(?:^|\s)(?:sudo\s+)?rm\s+(?:.*\s+)?-rf\s+\/(?:\s|$)/, reason: 'Attempting to delete root filesystem' }, { pattern: /(?:^|\s)(?:sudo\s+)?rm\s+(?:.*\s+)?-rf\s+\/\*/, reason: 'Attempting to delete all files in root' }, { pattern: /(?:^|\s)(?:sudo\s+)?rm\s+(?:.*\s+)?-rf\s+~\/\*/, reason: 'Attempting to delete all files in home directory' }, { pattern: /(?:^|\s)(?:sudo\s+)?rm\s+.*--no-preserve-root.*\/(?:\s|$)/, reason: 'Root deletion with no-preserve-root flag' }, { pattern: /(?:^|\s)(?:sudo\s+)?rm\s+(?:.*\s+)?-rf\s+\/(?:etc|var|usr|bin|sbin|lib|boot|dev|sys|proc)(?:\s|\/|$)/i, reason: 'Attempting to delete critical system directory' }, { pattern: /(?:^|\s)(?:sudo\s+)?rm\s+(?:.*\s+)?-rf\s+\/data\//, reason: 'Attempting to delete data directory' }, // Disk operations { pattern: /dd\s+.*of=\/dev\/[sh]d[a-z](?:\d|$)/, reason: 'Direct disk write operations are dangerous' }, { pattern: /mkfs\.[a-z0-9]+\s+\/dev\//, reason: 'Filesystem formatting commands are dangerous' }, { pattern: />\s*\/dev\/[sh]d[a-z]/, reason: 'Direct disk write operations are dangerous' }, { pattern: /fdisk\s+\/dev\//, reason: 'Disk partitioning commands are dangerous' }, { pattern: /parted\s+.*\/dev\//, reason: 'Disk partitioning commands are dangerous' }, // Docker destruction { pattern: /docker\s+system\s+prune.*(?:-a|--all).*(?:--volumes|-v)/, reason: 'Mass Docker cleanup with volumes is dangerous' }, { pattern: /docker\s+system\s+prune.*(?:--volumes|-v).*(?:-a|--all)/, reason: 'Mass Docker cleanup with volumes is dangerous' }, { pattern: /docker\s+volume\s+prune.*(?:-f|--force)/, reason: 'Forced Docker volume deletion is dangerous' }, { pattern: /docker\s+compose\s+down.*--volumes/, reason: 'Docker compose with volume deletion is dangerous' }, { pattern: /docker-compose\s+down.*--volumes/, reason: 'Docker compose with volume deletion is dangerous' }, // Service disruption { pattern: /(?:^|\s)(?:sudo\s+)?systemctl\s+(?:stop|disable|mask)\s+(?:docker|ssh|sshd|vssh)(?:\s|$)/, reason: 'Stopping critical services is dangerous' }, { pattern: /(?:^|\s)(?:sudo\s+)?service\s+(?:docker|ssh|sshd|vssh)\s+(?:stop|disable)/, reason: 'Stopping critical services is dangerous' }, // Network disruption { pattern: /iptables\s+-F/, reason: 'Flushing firewall rules is dangerous' }, { pattern: /iptables\s+--flush/, reason: 'Flushing firewall rules is dangerous' }, { pattern: /ufw\s+(?:disable|--force\s+reset)/, reason: 'Disabling firewall is dangerous' }, // System files { pattern: />\s*\/etc\/(?:passwd|shadow|group|sudoers)/, reason: 'Overwriting critical system files' }, { pattern: /(?:^|\s)(?:sudo\s+)?rm\s+.*\/etc\/(?:passwd|shadow|group|sudoers)/, reason: 'Deleting critical system files' }, { pattern: /(?:^|\s)(?:sudo\s+)?truncate\s+.*\/etc\/(?:passwd|shadow|group|sudoers)/, reason: 'Truncating critical system files' }, // System shutdown/reboot { pattern: /(?:^|\s)(?:sudo\s+)?(?:shutdown|poweroff|halt|reboot|init\s+0|init\s+6)(?:\s|$)/, reason: 'System shutdown/reboot commands are dangerous' }, // Permissions { pattern: /chmod\s+(?:-R\s+)?777\s+\//, reason: 'Making entire filesystem world-writable' }, { pattern: /chown\s+(?:-R\s+)?.*:.*\s+\/(?:\s|$)/, reason: 'Changing ownership of entire filesystem' }, // Fork bombs and malicious patterns { pattern: /:\s*\(\)\s*{\s*:\s*\|\s*:\s*&\s*}\s*;?\s*:/, reason: 'Fork bomb detected' }, { pattern: /\$\(.*\)\s*{\s*\$\(.*\)\|.*&\s*}/, reason: 'Potential fork bomb pattern' }, ]; CommandGuard.SUSPICIOUS_PATTERNS = [ { pattern: /curl\s+.*\|\s*(?:bash|sh)/, reason: 'Downloading and executing scripts directly' }, { pattern: /wget\s+.*\|\s*(?:bash|sh)/, reason: 'Downloading and executing scripts directly' }, { pattern: /eval\s+.*curl/, reason: 'Evaluating downloaded content' }, { pattern: /eval\s+.*wget/, reason: 'Evaluating downloaded content' }, ]; //# sourceMappingURL=command-guard.js.map