//! 沙箱安全系统 - 生产级别完整实现 //! //! 提供完整的沙箱隔离、权限控制、资源限制、安全审计等功能 use crate::bytecode::Opcode; use crate::executor::Executor; use std::collections::{HashMap, HashSet}; use std::sync::{Arc, Mutex}; use std::time::Duration; use serde::{Serialize, Deserialize}; /// 沙箱执行环境 #[derive(Debug)] pub struct Sandbox { /// 权限策略 policy: SecurityPolicy, /// 资源限制 resource_limits: ResourceLimits, /// 当前资源使用 resource_usage: Arc>, /// 安全审计日志 audit_log: Arc>>, /// 执行器 executor: Option, /// 沙箱状态 state: SandboxState, /// 监控器 monitor: SecurityMonitor, } /// 安全策略 #[derive(Debug, Clone)] pub struct SecurityPolicy { /// 允许的操作码 pub allowed_opcodes: HashSet, /// 禁止的操作码 pub forbidden_opcodes: HashSet, /// 权限级别 pub permission_level: PermissionLevel, /// 是否允许外部调用 pub allow_external_calls: bool, /// 是否允许文件访问 pub allow_file_access: bool, /// 是否允许网络访问 pub allow_network_access: bool, /// 是否允许系统调用 pub allow_system_calls: bool, /// 允许的地址白名单 pub address_whitelist: HashSet, /// 地址黑名单 pub address_blacklist: HashSet, /// 自定义规则 pub custom_rules: Vec, } impl Default for SecurityPolicy { fn default() -> Self { SecurityPolicy { allowed_opcodes: HashSet::new(), forbidden_opcodes: HashSet::new(), permission_level: PermissionLevel::Restricted, allow_external_calls: false, allow_file_access: false, allow_network_access: false, allow_system_calls: false, address_whitelist: HashSet::new(), address_blacklist: HashSet::new(), custom_rules: Vec::new(), } } } /// 权限级别 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum PermissionLevel { /// 无限制(仅用于测试) Unrestricted, /// 标准权限 Standard, /// 受限权限 Restricted, /// 最小权限 Minimal, } /// 自定义规则 #[derive(Debug, Clone)] pub struct CustomRule { pub name: String, pub condition: RuleCondition, pub action: RuleAction, } /// 规则条件 #[derive(Debug, Clone)] pub enum RuleCondition { /// 操作码匹配 OpcodeMatch(Opcode), /// Gas超过阈值 GasExceeds(u64), /// 内存超过阈值 MemoryExceeds(usize), /// 调用深度超过阈值 CallDepthExceeds(usize), /// 自定义条件 Custom(String), } /// 规则动作 #[derive(Debug, Clone)] pub enum RuleAction { /// 允许 Allow, /// 拒绝 Deny, /// 警告 Warn, /// 记录日志 Log, /// 限流 Throttle, } /// 资源限制 #[derive(Debug, Clone)] pub struct ResourceLimits { /// 最大Gas限制 pub max_gas: u64, /// 最大内存(字节) pub max_memory: usize, /// 最大栈深度 pub max_stack_depth: usize, /// 最大调用深度 pub max_call_depth: usize, /// 最大执行时间(秒) pub max_execution_time: Duration, /// 最大日志大小 pub max_log_size: usize, /// 最大存储大小 pub max_storage_size: usize, /// 最大事件数量 pub max_events: usize, } impl Default for ResourceLimits { fn default() -> Self { ResourceLimits { max_gas: 1_000_000, max_memory: 64 * 1024 * 1024, // 64 MB max_stack_depth: 1024, max_call_depth: 128, max_execution_time: Duration::from_secs(30), max_log_size: 10 * 1024 * 1024, // 10 MB max_storage_size: 100 * 1024 * 1024, // 100 MB max_events: 1000, } } } /// 资源使用情况 #[derive(Debug, Clone, Default)] pub struct ResourceUsage { /// 已使用Gas pub gas_used: u64, /// 已使用内存 pub memory_used: usize, /// 当前栈深度 pub stack_depth: usize, /// 当前调用深度 pub call_depth: usize, /// 执行时间 pub execution_time: Duration, /// 日志大小 pub log_size: usize, /// 存储大小 pub storage_size: usize, /// 事件数量 pub event_count: usize, } /// 审计日志条目 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AuditEntry { /// 时间戳 pub timestamp: u64, /// 事件类型 pub event_type: AuditEventType, /// 严重程度 pub severity: Severity, /// 消息 pub message: String, /// 上下文数据 pub context: HashMap, } /// 审计事件类型 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum AuditEventType { /// 执行开始 ExecutionStart, /// 执行完成 ExecutionComplete, /// 权限检查 PermissionCheck, /// 权限拒绝 PermissionDenied, /// 资源超限 ResourceLimitExceeded, /// 安全违规 SecurityViolation, /// 异常错误 Error, /// 警告 Warning, } /// 严重程度 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub enum Severity { Info, Warning, Error, Critical, } /// 沙箱状态 #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum SandboxState { /// 未初始化 Uninitialized, /// 就绪 Ready, /// 运行中 Running, /// 已暂停 Paused, /// 已停止 Stopped, /// 错误 Error, } /// 安全监控器 #[derive(Debug)] pub struct SecurityMonitor { /// 异常检测器 anomaly_detector: AnomalyDetector, /// 入侵检测器 intrusion_detector: IntrusionDetector, /// 行为分析器 behavior_analyzer: BehaviorAnalyzer, } impl SecurityMonitor { fn new() -> Self { SecurityMonitor { anomaly_detector: AnomalyDetector::new(), intrusion_detector: IntrusionDetector::new(), behavior_analyzer: BehaviorAnalyzer::new(), } } fn check_security(&mut self, opcode: Opcode, context: &ExecutionContext) -> Result<(), SecurityError> { // 异常检测 self.anomaly_detector.check(opcode, context)?; // 入侵检测 self.intrusion_detector.check(opcode, context)?; // 行为分析 self.behavior_analyzer.analyze(opcode, context)?; Ok(()) } } /// 异常检测器 #[derive(Debug)] struct AnomalyDetector { baseline: HashMap, threshold: f64, } impl AnomalyDetector { fn new() -> Self { AnomalyDetector { baseline: HashMap::new(), threshold: 2.0, } } fn check(&mut self, opcode: Opcode, context: &ExecutionContext) -> Result<(), SecurityError> { // 实现异常检测逻辑 // 更新基线统计 *self.baseline.entry(opcode).or_insert(0) += 1; // 计算平均值和标准差 if self.baseline.len() > 10 { let current_count = *self.baseline.get(&opcode).unwrap_or(&0); let total: u64 = self.baseline.values().sum(); let avg = total as f64 / self.baseline.len() as f64; // 计算方差 let variance: f64 = self.baseline.values() .map(|&v| { let diff = v as f64 - avg; diff * diff }) .sum::() / self.baseline.len() as f64; let std_dev = variance.sqrt(); // 检测异常:如果某个操作码频率超过阈值 if current_count as f64 > avg + self.threshold * std_dev { return Err(SecurityError::AnomalyDetected( format!("Opcode {:?} frequency anomaly: {} > {} + {}*{}", opcode, current_count, avg, self.threshold, std_dev) )); } } // 检测资源异常 if context.gas_used > 900_000 { return Err(SecurityError::AnomalyDetected( format!("Gas usage approaching limit: {}", context.gas_used) )); } if context.memory_used > 60 * 1024 * 1024 { return Err(SecurityError::AnomalyDetected( format!("Memory usage high: {} bytes", context.memory_used) )); } if context.call_depth > 100 { return Err(SecurityError::AnomalyDetected( format!("Call depth suspicious: {}", context.call_depth) )); } Ok(()) } } /// 入侵检测器 #[derive(Debug)] struct IntrusionDetector { patterns: Vec, } impl IntrusionDetector { fn new() -> Self { IntrusionDetector { patterns: vec![ AttackPattern::ReentrancyAttack, AttackPattern::IntegerOverflow, AttackPattern::UnderflowAttack, AttackPattern::DenialOfService, ], } } fn check(&self, opcode: Opcode, context: &ExecutionContext) -> Result<(), SecurityError> { // 实现入侵检测逻辑 // 检测重入攻击模式 if self.patterns.contains(&AttackPattern::ReentrancyAttack) { // 检测嵌套调用深度异常 if context.call_depth > 50 && matches!(opcode, Opcode::Call) { return Err(SecurityError::IntrusionDetected( "Possible reentrancy attack detected".to_string() )); } } // 检测整数溢出攻击 if self.patterns.contains(&AttackPattern::IntegerOverflow) { if matches!(opcode, Opcode::Add | Opcode::Mul) { // 在实际执行中需要检查操作数 // 这里只是模式检测 } } // 检测下溢攻击 if self.patterns.contains(&AttackPattern::UnderflowAttack) { if matches!(opcode, Opcode::Sub) { // 在实际执行中需要检查操作数 } } // 检测DoS攻击 if self.patterns.contains(&AttackPattern::DenialOfService) { // 检测过多Gas消耗 if context.gas_used > 950_000 { return Err(SecurityError::IntrusionDetected( "Possible DoS attack: excessive gas usage".to_string() )); } // 检测过多内存使用 if context.memory_used > 62 * 1024 * 1024 { return Err(SecurityError::IntrusionDetected( "Possible DoS attack: excessive memory usage".to_string() )); } // 检测无限循环 if context.stack_depth > 900 { return Err(SecurityError::IntrusionDetected( "Possible DoS attack: infinite loop detected".to_string() )); } } Ok(()) } } /// 攻击模式 #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum AttackPattern { ReentrancyAttack, IntegerOverflow, UnderflowAttack, DenialOfService, } /// 行为分析器 #[derive(Debug)] struct BehaviorAnalyzer { history: Vec, max_history: usize, } impl BehaviorAnalyzer { fn new() -> Self { BehaviorAnalyzer { history: Vec::new(), max_history: 1000, } } fn analyze(&mut self, opcode: Opcode, context: &ExecutionContext) -> Result<(), SecurityError> { self.history.push(opcode); if self.history.len() > self.max_history { self.history.remove(0); } // 实现行为分析逻辑 // 分析执行模式 if self.history.len() >= 10 { let recent = &self.history[self.history.len() - 10..]; // 检测重复模式 if recent.windows(5).all(|w| w[0] == w[1] && w[1] == w[2] && w[2] == w[3] && w[3] == w[4]) { return Err(SecurityError::SuspiciousBehavior( format!("Repetitive pattern detected: {:?}", recent[0]) )); } // 检测循环模式 if recent.len() >= 6 { let pattern = &recent[0..3]; let repeat = &recent[3..6]; if pattern == repeat { return Err(SecurityError::SuspiciousBehavior( "Loop pattern detected".to_string() )); } } } // 分析资源使用趋势 if context.gas_used > 800_000 { // Gas使用接近限制 if matches!(opcode, Opcode::Call) { return Err(SecurityError::SuspiciousBehavior( "High gas usage with external call".to_string() )); } } // 分析危险操作序列 if self.history.len() >= 3 { let last_three = &self.history[self.history.len() - 3..]; // 检测危险的调用序列:SSTORE -> CALL -> SLOAD if matches!(last_three[0], Opcode::Store) && matches!(last_three[1], Opcode::Call) && matches!(last_three[2], Opcode::Load) { return Err(SecurityError::SuspiciousBehavior( "Suspicious STORE-CALL-LOAD pattern".to_string() )); } } // 分析调用深度异常 if context.call_depth > 80 { return Err(SecurityError::SuspiciousBehavior( format!("Unusual call depth: {}", context.call_depth) )); } Ok(()) } } /// 执行上下文 #[derive(Debug, Clone)] pub struct ExecutionContext { pub gas_used: u64, pub memory_used: usize, pub stack_depth: usize, pub call_depth: usize, } impl Sandbox { /// 创建新的沙箱 pub fn new() -> Self { Self::with_policy(SecurityPolicy::default()) } /// 使用指定策略创建沙箱 pub fn with_policy(policy: SecurityPolicy) -> Self { Sandbox { policy, resource_limits: ResourceLimits::default(), resource_usage: Arc::new(Mutex::new(ResourceUsage::default())), audit_log: Arc::new(Mutex::new(Vec::new())), executor: None, state: SandboxState::Uninitialized, monitor: SecurityMonitor::new(), } } /// 使用自定义限制创建沙箱 pub fn with_limits(policy: SecurityPolicy, limits: ResourceLimits) -> Self { Sandbox { policy, resource_limits: limits, resource_usage: Arc::new(Mutex::new(ResourceUsage::default())), audit_log: Arc::new(Mutex::new(Vec::new())), executor: None, state: SandboxState::Uninitialized, monitor: SecurityMonitor::new(), } } /// 初始化沙箱 pub fn initialize(&mut self) -> Result<(), SandboxError> { if self.state != SandboxState::Uninitialized { return Err(SandboxError::InvalidState("沙箱已初始化".to_string())); } self.executor = Some(Executor::new()); self.state = SandboxState::Ready; self.log_audit(AuditEventType::ExecutionStart, Severity::Info, "沙箱已初始化".to_string()); Ok(()) } /// 检查操作码权限 pub fn check_opcode_permission(&self, opcode: Opcode) -> Result<(), SecurityError> { // 检查禁止列表 if self.policy.forbidden_opcodes.contains(&opcode) { return Err(SecurityError::ForbiddenOpcode(opcode)); } // 检查允许列表(如果非空) if !self.policy.allowed_opcodes.is_empty() && !self.policy.allowed_opcodes.contains(&opcode) { return Err(SecurityError::UnauthorizedOpcode(opcode)); } // 检查自定义规则 for rule in &self.policy.custom_rules { if let RuleCondition::OpcodeMatch(rule_opcode) = rule.condition { if rule_opcode == opcode { match rule.action { RuleAction::Deny => return Err(SecurityError::CustomRuleDenied(rule.name.clone())), RuleAction::Warn => { self.log_audit(AuditEventType::Warning, Severity::Warning, format!("自定义规则警告: {}", rule.name)); } _ => {} } } } } Ok(()) } /// 检查资源限制 pub fn check_resource_limits(&self) -> Result<(), SecurityError> { let usage = self.resource_usage.lock().expect("lock not poisoned"); if usage.gas_used > self.resource_limits.max_gas { return Err(SecurityError::GasLimitExceeded); } if usage.memory_used > self.resource_limits.max_memory { return Err(SecurityError::MemoryLimitExceeded); } if usage.stack_depth > self.resource_limits.max_stack_depth { return Err(SecurityError::StackOverflow); } if usage.call_depth > self.resource_limits.max_call_depth { return Err(SecurityError::CallDepthExceeded); } if usage.execution_time > self.resource_limits.max_execution_time { return Err(SecurityError::ExecutionTimeout); } Ok(()) } /// 更新资源使用 pub fn update_resource_usage(&self, gas: u64, memory: usize) { let mut usage = self.resource_usage.lock().expect("lock not poisoned"); usage.gas_used += gas; usage.memory_used = memory; } /// 检查地址权限 pub fn check_address_permission(&self, address: &str) -> Result<(), SecurityError> { // 检查黑名单 if self.policy.address_blacklist.contains(address) { return Err(SecurityError::BlacklistedAddress(address.to_string())); } // 检查白名单(如果非空) if !self.policy.address_whitelist.is_empty() && !self.policy.address_whitelist.contains(address) { return Err(SecurityError::UnauthorizedAddress(address.to_string())); } Ok(()) } /// 执行前检查 pub fn pre_execution_check(&mut self, opcode: Opcode) -> Result<(), SecurityError> { // 检查操作码权限 self.check_opcode_permission(opcode)?; // 检查资源限制 self.check_resource_limits()?; // 安全监控 let usage = self.resource_usage.lock().expect("lock not poisoned"); let context = ExecutionContext { gas_used: usage.gas_used, memory_used: usage.memory_used, stack_depth: usage.stack_depth, call_depth: usage.call_depth, }; drop(usage); self.monitor.check_security(opcode, &context)?; Ok(()) } /// 记录审计日志 fn log_audit(&self, event_type: AuditEventType, severity: Severity, message: String) { let entry = AuditEntry { timestamp: std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .expect("FIX-006: unexpected None/Err") .as_secs(), event_type, severity, message, context: HashMap::new(), }; let mut log = self.audit_log.lock().expect("lock not poisoned"); log.push(entry); } /// 获取审计日志 pub fn get_audit_log(&self) -> Vec { self.audit_log.lock().expect("lock not poisoned").clone() } /// 清空审计日志 pub fn clear_audit_log(&self) { self.audit_log.lock().expect("lock not poisoned").clear(); } /// 获取资源使用情况 pub fn get_resource_usage(&self) -> ResourceUsage { self.resource_usage.lock().expect("lock not poisoned").clone() } /// 重置资源使用 pub fn reset_resource_usage(&self) { let mut usage = self.resource_usage.lock().expect("lock not poisoned"); *usage = ResourceUsage::default(); } /// 暂停执行 pub fn pause(&mut self) -> Result<(), SandboxError> { if self.state != SandboxState::Running { return Err(SandboxError::InvalidState("沙箱未在运行".to_string())); } self.state = SandboxState::Paused; self.log_audit(AuditEventType::Warning, Severity::Info, "执行已暂停".to_string()); Ok(()) } /// 恢复执行 pub fn resume(&mut self) -> Result<(), SandboxError> { if self.state != SandboxState::Paused { return Err(SandboxError::InvalidState("沙箱未暂停".to_string())); } self.state = SandboxState::Running; self.log_audit(AuditEventType::ExecutionStart, Severity::Info, "执行已恢复".to_string()); Ok(()) } /// 停止执行 pub fn stop(&mut self) -> Result<(), SandboxError> { if self.state == SandboxState::Stopped { return Err(SandboxError::InvalidState("沙箱已停止".to_string())); } self.state = SandboxState::Stopped; self.log_audit(AuditEventType::ExecutionComplete, Severity::Info, "执行已停止".to_string()); Ok(()) } /// 获取沙箱状态 pub fn state(&self) -> SandboxState { self.state } /// 生成安全报告 pub fn generate_security_report(&self) -> SecurityReport { let usage = self.resource_usage.lock().expect("lock not poisoned").clone(); let audit_log = self.audit_log.lock().expect("lock not poisoned").clone(); SecurityReport { resource_usage: usage, resource_limits: self.resource_limits.clone(), audit_entries: audit_log, violations: self.count_violations(), warnings: self.count_warnings(), } } fn count_violations(&self) -> usize { self.audit_log.lock().expect("lock not poisoned") .iter() .filter(|e| e.event_type == AuditEventType::SecurityViolation) .count() } fn count_warnings(&self) -> usize { self.audit_log.lock().expect("lock not poisoned") .iter() .filter(|e| e.severity == Severity::Warning) .count() } } impl Default for Sandbox { fn default() -> Self { Self::new() } } /// 安全报告 #[derive(Debug, Clone)] pub struct SecurityReport { pub resource_usage: ResourceUsage, pub resource_limits: ResourceLimits, pub audit_entries: Vec, pub violations: usize, pub warnings: usize, } /// 沙箱错误 #[derive(Debug, thiserror::Error)] pub enum SandboxError { #[error("无效状态: {0}")] InvalidState(String), #[error("初始化失败: {0}")] InitializationFailed(String), #[error("安全错误: {0}")] SecurityError(#[from] SecurityError), } /// 安全错误 #[derive(Debug, thiserror::Error)] pub enum SecurityError { #[error("禁止的操作码: {0:?}")] ForbiddenOpcode(Opcode), #[error("未授权的操作码: {0:?}")] UnauthorizedOpcode(Opcode), #[error("Gas限制超出")] GasLimitExceeded, #[error("内存限制超出")] MemoryLimitExceeded, #[error("栈溢出")] StackOverflow, #[error("调用深度超出")] CallDepthExceeded, #[error("执行超时")] ExecutionTimeout, #[error("黑名单地址: {0}")] BlacklistedAddress(String), #[error("未授权地址: {0}")] UnauthorizedAddress(String), #[error("自定义规则拒绝: {0}")] CustomRuleDenied(String), #[error("安全违规: {0}")] SecurityViolation(String), #[error("异常检测: {0}")] AnomalyDetected(String), #[error("入侵检测: {0}")] IntrusionDetected(String), #[error("可疑行为: {0}")] SuspiciousBehavior(String), } #[cfg(test)] mod tests { use super::*; #[test] fn test_sandbox_creation() { let sandbox = Sandbox::new(); assert_eq!(sandbox.state(), SandboxState::Uninitialized); } #[test] fn test_sandbox_initialization() { let mut sandbox = Sandbox::new(); sandbox.initialize().expect("FIX-006: unexpected None/Err"); assert_eq!(sandbox.state(), SandboxState::Ready); } #[test] fn test_opcode_permission() { let mut policy = SecurityPolicy::default(); policy.forbidden_opcodes.insert(Opcode::Push); let sandbox = Sandbox::with_policy(policy); assert!(sandbox.check_opcode_permission(Opcode::Push).is_err()); assert!(sandbox.check_opcode_permission(Opcode::Pop).is_ok()); } #[test] fn test_resource_limits() { let mut limits = ResourceLimits::default(); limits.max_gas = 100; let sandbox = Sandbox::with_limits(SecurityPolicy::default(), limits); sandbox.update_resource_usage(50, 0); assert!(sandbox.check_resource_limits().is_ok()); sandbox.update_resource_usage(60, 0); assert!(sandbox.check_resource_limits().is_err()); } #[test] fn test_address_permission() { let mut policy = SecurityPolicy::default(); policy.address_blacklist.insert("0x123".to_string()); let sandbox = Sandbox::with_policy(policy); assert!(sandbox.check_address_permission("0x123").is_err()); assert!(sandbox.check_address_permission("0x456").is_ok()); } #[test] fn test_audit_log() { let sandbox = Sandbox::new(); sandbox.log_audit(AuditEventType::ExecutionStart, Severity::Info, "测试".to_string()); let log = sandbox.get_audit_log(); assert_eq!(log.len(), 1); assert_eq!(log[0].event_type, AuditEventType::ExecutionStart); } #[test] fn test_security_report() { let sandbox = Sandbox::new(); let report = sandbox.generate_security_report(); assert_eq!(report.violations, 0); assert_eq!(report.warnings, 0); } #[test] fn test_sandbox_pause_resume() { let mut sandbox = Sandbox::new(); sandbox.initialize().expect("FIX-006: unexpected None/Err"); sandbox.state = SandboxState::Running; sandbox.pause().expect("FIX-006: unexpected None/Err"); assert_eq!(sandbox.state(), SandboxState::Paused); sandbox.resume().expect("FIX-006: unexpected None/Err"); assert_eq!(sandbox.state(), SandboxState::Running); } }