摘要:针对中央网信办发布的《关于OpenClaw“龙虾”的安全风险提示》,特别是其中提到的“权限边界模糊”与“缺乏审计机制”两大核心痛点,本文设计并实现了一套基于PowerShell的高危命令审批系统。该系统通过oc-safe安全包装器、四级风险动态评估、强制人工审批流及结构化审计日志,将AI的“自主执行权”关进笼子,实现了操作层面的最小权限控制与全流程可追溯。

1. 背景与痛点

随着AI Agent(如OpenClaw)的普及,其强大的自动化能力背后隐藏着巨大的安全风险。根据最新的安全风险提示,主要存在以下隐患:

  1. 权限边界模糊:AI可能因“幻觉”或被恶意提示词注入,执行rm -rfcurl | bash等高危命令,导致系统崩溃或数据丢失。
  2. 缺乏审计机制:默认情况下,AI的操作往往是“黑盒”的,一旦发生事故,难以界定是用户指令错误、AI逻辑幻觉还是外部攻击,导致责任无法追溯。

传统的“事后补救”已无法满足安全需求。我们需要在操作执行前建立一道“防火墙”,在操作执行后留下一本“明白账”。

2. 解决方案架构

本方案不依赖复杂的第三方安全软件,而是利用PowerShell的强大脚本能力,在OpenClaw工作流中嵌入一个中间件层

核心设计原则

  • 默认拒绝(Default Deny):所有高危命令默认拦截,必须经过显式审批。
  • 分级管控(Risk Grading):根据命令危害程度,分为禁止、高危(人工审)、中危(确认)、低危(自动过)。
  • 全量留痕(Full Auditing):所有操作(包括被拒绝的和强制执行的)均写入JSON日志。
  • 安全降级(Safe Fallback):提供safe-rm等替代方案,将不可逆操作转化为可恢复操作。

系统流程图

🔴 禁止级

🟠 高危级

🟡 中危级

🟢 低危级

批准

拒绝

用户/AI发起命令

oc-safe 包装器

风险引擎评估

直接阻断 & 记录

弹出人工审批界面

二次确认提示

自动执行

取消执行 & 记录

执行命令

写入审计日志 JSON

紧急模式 -Force

跳过审批但记录原因

3. 核心源码实现

以下是完整的集成脚本 集成审批系统.ps1。该脚本包含了风险识别、审批交互、安全别名注册及审计报表生成四大模块。

3.1 初始化与配置管理

首先定义系统目录结构和基础配置,确保日志和备份目录存在。

# 集成审批系统.ps1
# 版本: 1.0.0
# 功能: OpenClaw 高危命令审批与审计系统

$ScriptRoot = "C:\Users\Administrator\.openclaw\workspace"
$SecurityRoot = Join-Path $ScriptRoot "security"
$LogPath = Join-Path $SecurityRoot "logs\command-approvals.json"
$ConfigPath = Join-Path $SecurityRoot "config.json"

# 初始化目录
function Initialize-ApprovalSystem {
    Write-Host "=== 初始化高危命令审批系统 ===" -ForegroundColor Cyan
    $directories = @(
        $SecurityRoot,
        (Join-Path $SecurityRoot "logs"),
        (Join-Path $SecurityRoot "backups")
    )
    
    foreach ($dir in $directories) {
        if (-not (Test-Path $dir)) {
            New-Item -ItemType Directory -Path $dir -Force | Out-Null
            Write-Host "创建目录: $dir" -ForegroundColor Green
        }
    }

    # 默认配置
    $config = @{
        version = "1.0.0"
        enabled = $true
        require_approval = @("critical", "high", "medium")
        auto_approve = @("safe", "low")
        log_retention_days = 30
    }
    
    if (-not (Test-Path $ConfigPath)) {
        $config | ConvertTo-Json | Set-Content $ConfigPath
        Write-Host "创建默认配置文件" -ForegroundColor Green
    }
    
    # 注册安全函数
    Register-SafeAliases
    Write-Host "✅ 审批系统初始化完成" -ForegroundColor Green
}

3.2 风险引擎与审批交互核心

这是系统的“大脑”。它解析命令关键词,判定风险等级,并处理用户交互。

# 风险等级定义
enum RiskLevel { Safe, Low, Medium, High, Critical, Bypass }

# 简单的关键词风险匹配引擎 (生产环境可扩展为正则或AI分析)
function Test-CommandRisk {
    param([string]$Command)
    
    $cmdLower = $Command.ToLower()
    
    # 🔴 禁止级
    if ($cmdLower -match "rm\s+-rf\s+/" -or $cmdLower -match "format\s+[c-z]:" -or $cmdLower -match "shutdown\s+-h\s+now") {
        return @{ Level = [RiskLevel]::Critical; Description = "尝试删除根目录或格式化磁盘" }
    }
    
    # 🟠 高危级 (需人工审批)
    if ($cmdLower -match "rm\s+" -or $cmdLower -match "del\s+" -or $cmdLower -match "curl.*\|\s*bash" -or $cmdLower -match "kill\s+-9") {
        return @{ Level = [RiskLevel]::High; Description = "文件删除或远程代码执行风险" }
    }
    
    # 🟡 中危级 (需确认)
    if ($cmdLower -match "chmod\s+777" -or $cmdLower -match "net\s+user") {
        return @{ Level = [RiskLevel]::Medium; Description = "权限修改或用户管理操作" }
    }
    
    # 🟢 低危/安全级
    return @{ Level = [RiskLevel]::Low; Description = "常规查看或创建操作" }
}

# 写入审计日志
function Write-ApprovalLog {
    param(
        [string]$Command,
        [string]$RiskLevel,
        [string]$Action,
        [string]$Reason = ""
    )
    
    $logEntry = [PSCustomObject]@{
        Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        Command   = $Command
        RiskLevel = $RiskLevel
        Action    = $Action # Approved, Rejected, Forced, Blocked
        Reason    = $Reason
        User      = $env:USERNAME
    }
    
    $logs = @()
    if (Test-Path $LogPath) {
        $logs = Get-Content $LogPath | ConvertFrom-Json
    }
    $logs += $logEntry
    $logs | ConvertTo-Json | Set-Content $LogPath
}

# 核心执行函数:带审批流程
function Invoke-OpenClawCommand {
    param(
        [string]$Command,
        [switch]$Force
    )
    
    # 1. 强制模式处理
    if ($Force) {
        Write-Host "⚠️  强制模式:跳过审批 (需记录原因)" -ForegroundColor Yellow
        $reason = Read-Host "请输入强制执行的正当理由"
        Write-ApprovalLog -Command $Command -RiskLevel "Bypass" -Action "Forced" -Reason $reason
        
        try {
            Invoke-Expression $Command
            return $true
        } catch {
            Write-Host "❌ 命令执行失败: $_" -ForegroundColor Red
            return $false
        }
    }
    
    # 2. 风险评估
    $riskInfo = Test-CommandRisk -Command $Command
    
    # 3. 禁止级直接阻断
    if ($riskInfo.Level -eq [RiskLevel]::Critical) {
        Write-Host "🚫 禁止执行:$($riskInfo.Description)" -ForegroundColor Red
        Write-ApprovalLog -Command $Command -RiskLevel "Critical" -Action "Blocked" -Reason "系统禁止"
        return $false
    }
    
    # 4. 高危/中危 审批交互
    if ($riskInfo.Level -in @([RiskLevel]::High, [RiskLevel]::Medium)) {
        Write-Host "`n⚠️  高危命令需要审批" -ForegroundColor Yellow
        Write-Host "────────────────────────────"
        Write-Host "命令: $Command"
        Write-Host "类型: $($riskInfo.Description)"
        Write-Host "风险等级: $($riskInfo.Level)"
        Write-Host "────────────────────────────"
        
        $choice = Read-Host "是否批准执行? [Y] 批准  [N] 拒绝  [D] 详情"
        
        if ($choice -eq "Y") {
            Write-ApprovalLog -Command $Command -RiskLevel $riskInfo.Level -Action "Approved"
            Write-Host "✅ 已批准,正在执行..." -ForegroundColor Green
            try {
                Invoke-Expression $Command
                return $true
            } catch {
                Write-Host "❌ 执行出错: $_" -ForegroundColor Red
                return $false
            }
        } else {
            Write-ApprovalLog -Command $Command -RiskLevel $riskInfo.Level -Action "Rejected"
            Write-Host "❌ 操作已取消" -ForegroundColor Red
            return $false
        }
    }
    
    # 5. 低危自动通过
    Write-ApprovalLog -Command $Command -RiskLevel $riskInfo.Level -Action "AutoApproved"
    try {
        Invoke-Expression $Command
        return $true
    } catch {
        Write-Host "❌ 执行出错: $_" -ForegroundColor Red
        return $false
    }
}

3.3 安全替代方案(Safe Aliases)

为了进一步降低风险,我们提供了更安全的命令替代品,例如将“删除”变为“移至回收站”。

function Register-SafeAliases {
    # 安全删除:移动到回收站而非永久删除
    function safe-rm {
        param([string]$Path)
        if (Test-Path $Path) {
            Write-Host "🛡️ 安全模式:将文件移动到回收站: $Path" -ForegroundColor Cyan
            Add-Type -AssemblyName Microsoft.VisualBasic
            [Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($Path, 'OnlyErrorDialogs', 'SendToRecycleBin')
            Write-Host "✅ 操作完成" -ForegroundColor Green
        } else {
            Write-Host "⚠️ 文件不存在" -ForegroundColor Yellow
        }
    }
    
    # 安全下载:先下载到临时目录,检查后再移动
    function safe-download {
        param([string]$Url, [string]$OutputPath)
        $tempDir = "C:\Users\Administrator\.openclaw\temp\downloads"
        if (-not (Test-Path $tempDir)) { New-Item -ItemType Directory -Path $tempDir -Force | Out-Null }
        
        $tempFile = Join-Path $tempDir "dl_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
        Write-Host "⬇️ 正在下载到临时区..." -ForegroundColor Cyan
        Invoke-WebRequest -Uri $Url -OutFile $tempFile
        
        Write-Host "🔍 下载完成。文件大小:$((Get-Item $tempFile).Length) 字节"
        $confirm = Read-Host "确认复制到目标位置?[Y/N]"
        if ($confirm -eq "Y") {
            Copy-Item $tempFile $OutputPath -Force
            Write-Host "✅ 文件已保存至: $OutputPath" -ForegroundColor Green
        } else {
            Remove-Item $tempFile
            Write-Host "❌ 下载已取消,临时文件已清理" -ForegroundColor Yellow
        }
    }
    
    # 导出全局可用
    Set-Alias -Name oc-safe -Value Invoke-OpenClawCommand -Scope Global -Force
    Write-Host "🔧 已注册全局别名:oc-safe" -ForegroundColor Gray
}

3.4 审计报表生成

最后,提供一个一键生成安全审计报告的功能,方便定期自查。

function Get-SecurityAuditReport {
    Write-Host "📊 生成安全审计报告中..." -ForegroundColor Cyan
    
    $report = @"
# OpenClaw 安全审计报告
生成时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
审计员: $env:USERNAME

## 1. 统计概览
"@
    
    if (Test-Path $LogPath) {
        $logs = Get-Content $LogPath | ConvertFrom-Json
        $total = $logs.Count
        $blocked = ($logs | Where-Object { $_.Action -eq "Blocked" }).Count
        $approved = ($logs | Where-Object { $_.Action -eq "Approved" }).Count
        $forced = ($logs | Where-Object { $_.Action -eq "Forced" }).Count
        
        $report += @"
- 总操作数: $total
- 自动/批准执行: $approved
- 被系统阻断: $blocked
- 强制绕过审批: $forced

## 2. 近期高风险事件 (Top 5)
"@
        $recentRisks = $logs | Where-Object { $_.RiskLevel -in @('Critical', 'High') } | Select-Object -Last 5
        if ($recentRisks) {
            foreach ($log in $recentRisks) {
                $report += "- [$($log.Timestamp)] [$($log.Action)] $($log.Command)`n"
            }
        } else {
            $report += "- 无高风险记录`n"
        }
    } else {
        $report += "- 暂无日志记录`n"
    }
    
    $report += @"
## 3. 合规性自查
- [x] 高危命令审批机制已启用
- [x] 操作日志完整记录
- [!] 当前运行账户: $env:USERNAME (建议非Administrator)
"@
    
    # 保存报告
    $reportFile = Join-Path $SecurityRoot "audit-report-$(Get-Date -Format 'yyyyMMdd').md"
    $report | Set-Content $reportFile
    Write-Host "✅ 报告已保存至: $reportFile" -ForegroundColor Green
    Write-Host $report -ForegroundColor Gray
}

4. 使用指南

4.1 安装与初始化

将上述代码保存为 集成审批系统.ps1,放置在OpenClaw的工作空间目录(如 C:\Users\Administrator\.openclaw\workspace\)。

在PowerShell中运行:

cd C:\Users\Administrator\.openclaw\workspace
. .\集成审批系统.ps1
Initialize-ApprovalSystem

4.2 日常使用

安装后,系统将自动注册 oc-safe 别名。

  • 推荐用法:让OpenClaw在执行任何命令时,自动调用 oc-safe "命令内容"

    # 示例:尝试删除文件(会触发审批)
    oc-safe "rm -rf test_folder"
    
    # 示例:查看文件(自动通过)
    oc-safe "ls -la"
    
    # 示例:使用安全替代方案
    safe-rm "important_data.txt" 
    
  • 紧急情况:若确需跳过审批(如自动化脚本卡死),使用 -Force 参数,但必须输入理由。

    oc-safe "restart-service spooler" -Force
    

4.3 定期审计

每周运行一次审计命令,查看是否有异常的高频阻断或强制绕过行为:

Get-SecurityAuditReport

5. 方案优势与局限性分析

优势

  1. 零成本落地:无需购买额外硬件或软件,纯脚本实现,兼容所有Windows环境。
  2. 细粒度控制:不仅仅是“允许/拒绝”,而是根据命令语义进行动态分级。
  3. 证据链完整:JSON格式的日志易于对接后续的SIEM系统或进行数据分析。
  4. 人性化设计:提供safe-rm等“后悔药”机制,减少误操作带来的实际损失。

局限性与改进方向

  • 权限依赖:当前脚本运行在宿主账户权限下。如果宿主是Administrator,且攻击者能绕过PowerShell直接调用API,则防线可能失效。终极方案应配合OS层面的低权限账户运行OpenClaw。
  • 网络层缺失:本方案主要管控本地命令,对于网络层面的数据外传(如Token泄露)需配合防火墙策略。
  • 防篡改:日志文件目前为明文JSON,高级攻击者可能修改日志。生产环境建议增加日志签名或远程实时同步。

6. 结语

面对AI Agent带来的新安全挑战,“信任但要验证”(Trust but Verify)是唯一准则。本文提供的方案通过代码级的审批流全量的审计日志,为OpenClaw穿上了一层“防弹衣”。虽然它不能解决所有安全问题,但在操作权限控制事故定责这两个关键维度上,它提供了一套行之有效、立竿见影的防御手段。

安全不是可选项,而是AI时代的必选项。希望这套脚本能为您的AI探索之路保驾护航。


作者:[绘梨衣的sakura路]
参考文档:中央网信办关于OpenClaw“龙虾”的安全风险提示

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐