918 lines
27 KiB
Rust
918 lines
27 KiB
Rust
//! 沙箱安全系统 - 生产级别完整实现
|
||
//!
|
||
//! 提供完整的沙箱隔离、权限控制、资源限制、安全审计等功能
|
||
|
||
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<Mutex<ResourceUsage>>,
|
||
/// 安全审计日志
|
||
audit_log: Arc<Mutex<Vec<AuditEntry>>>,
|
||
/// 执行器
|
||
executor: Option<Executor>,
|
||
/// 沙箱状态
|
||
state: SandboxState,
|
||
/// 监控器
|
||
monitor: SecurityMonitor,
|
||
}
|
||
|
||
/// 安全策略
|
||
#[derive(Debug, Clone)]
|
||
pub struct SecurityPolicy {
|
||
/// 允许的操作码
|
||
pub allowed_opcodes: HashSet<Opcode>,
|
||
/// 禁止的操作码
|
||
pub forbidden_opcodes: HashSet<Opcode>,
|
||
/// 权限级别
|
||
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<String>,
|
||
/// 地址黑名单
|
||
pub address_blacklist: HashSet<String>,
|
||
/// 自定义规则
|
||
pub custom_rules: Vec<CustomRule>,
|
||
}
|
||
|
||
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<String, String>,
|
||
}
|
||
|
||
/// 审计事件类型
|
||
#[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<Opcode, u64>,
|
||
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::<f64>() / 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<AttackPattern>,
|
||
}
|
||
|
||
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<Opcode>,
|
||
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<AuditEntry> {
|
||
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<AuditEntry>,
|
||
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);
|
||
}
|
||
}
|