在openclaw原基础扩展插件,提供了敏感操作的二次认证功能的实现
主要特性包括:敏感命令自动检测、多用户隔离验证状态、白名单机制、验证成功通知等。插件通过HTTP服务器(18800端口)提供验证页面,采用会话管理机制跟踪验证状态,并支持验证码刷新功能。安装只需将插件放入extensions目录并安装依赖即可。
openclaw 二次认证(以图形验证码为例)插件说明
概述
image-captcha-auth 扩展插件为 OpenClaw 提供了敏感操作的二次认证功能。当用户尝试执行包含敏感关键词的命令时,系统会拦截操作并要求用户通过图形验证码进行身份验证。最重要不修改任何源代码哦!
预览截图

功能特性
| 功能 | 说明 |
|---|---|
| 敏感命令检测 | 自动检测 bash、exec、runCommand 等工具中的敏感操作 |
| 图形验证码 | 生成 4 位数字的 SVG 图形验证码,带干扰线和噪点 |
| 验证码有效期 | 验证码生成后 300 秒(5 分钟)内有效 |
| 验证通过免验证 | 验证成功后 300 秒(5 分钟)内无需再次验证 |
| 多用户隔离 | 每个用户的验证状态独立管理 |
| 自动通知 | 验证成功后自动通过配置的消息渠道发送通知 |
| 验证码刷新 | 支持点击图片刷新验证码 |
| 白名单机制 | 支持配置白名单用户,跳过验证 |
敏感操作关键词
以下关键词会触发二次认证:
delete- 删除命令remove- 移除命令rm- 删除命令unlink- 删除链接命令rmdir- 删除目录命令format- 格式化命令wipe- 擦除命令erase- 擦除命令exec- 执行命令eval- 执行表达式system- 系统命令shell- Shell 命令bash- Bash 命令sudo- 超级用户命令su- 切换用户命令chmod- 修改权限命令chown- 修改所有者命令restart- 重启命令shutdown- 关机命令reboot- 重启命令gateway- 网关命令
配置参数
配置文件:extensions/image-captcha-auth/src/config.ts
| 参数 | 默认值 | 说明 |
|---|---|---|
port |
18800 | HTTP 服务器端口 |
timeout |
300000 | 验证码有效期(毫秒,默认 5 分钟) |
verificationDuration |
300000 | 验证通过后免验证有效期(毫秒,默认 5 分钟) |
debug |
false | 调试模式 |
sensitiveKeywords |
见配置 | 敏感关键词列表 |
allowlistUsers |
[] | 白名单用户列表(跳过验证) |
安装与使用
安装插件
- 将
image-captcha-auth目录放置在 OpenClaw 的extensions/目录下 - 进入插件目录并安装依赖:
cd extensions/image-captcha-auth npm install - 重启 OpenClaw 网关,插件会自动加载
验证插件已加载
查看网关日志,应显示:
[image-captcha-auth] HTTP server running on http://localhost:18800
image-captcha-auth plugin loaded
使用流程
1. 用户发送敏感命令
用户在钉钉中发送包含敏感操作的命令:
请使用 bash 工具删除文件 C:\Users\DabbyDesign\Desktop\test.txt
2. 系统拦截并返回验证链接
机器人检测到敏感操作,阻止执行并返回验证链接:
🔐 该操作需要二次认证
检测到敏感操作: Remove-Item "C:\Users\DabbyDesign\Desktop\test.txt"
请点击以下链接完成验证:
http://localhost:18800/captcha/2aa5803b-e83a-4723-a5b6-ea5e5e4d0b12
验证码有效期: 300 秒
验证成功后,请重新发送命令。
3. 用户打开验证页面
浏览器访问验证链接,显示图形验证码页面:
- 显示待验证操作的命令预览
- 显示 4 位数字验证码(带干扰线)
- 显示剩余时间倒计时
- 输入框用于输入验证码
- 验证按钮提交验证
- 支持点击验证码图片刷新
4. 用户输入验证码
用户查看验证码图片,输入 4 位数字,点击验证按钮或按 Enter 键提交。如果验证码识别困难,可以点击图片刷新验证码。
5. 验证成功后发送通知
系统验证通过后,自动向钉钉发送通知:
✅ 二次认证成功!
验证的有效期为 300 秒。
请重新发送命令以执行操作。
6. 重新发送命令
用户在 5 分钟内重新发送之前的命令,系统自动放行并执行操作。
技术实现
架构图
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ 钉钉用户 │────────▶│ OpenClaw网关 │────────▶│ 验证服务器 │
│ (以钉钉为例) │ │ (插件系统) │ │ (HTTP:18800)│
└─────────────┘ └──────────────┘ └─────────────┘
│ │ │
│ │ │
│ ▼ │
│ ┌──────────────┐ │
│ │ CaptchaManager│ │
│ │ (会话管理) │ │
│ └──────────────┘ │
│ │ │
└────────────────────────┘ │
(通知) │
◀─────────────────────┘
核心模块
1. CaptchaManager(验证码管理器)
负责管理所有验证会话和用户验证状态。
主要方法:
generate(userId, context)- 生成新的验证会话verify(sessionId, code, userId)- 验证验证码isUserVerified(userId)- 检查用户是否已验证getSession(sessionId)- 获取验证会话clearExpiredSessions()- 清理过期会话
数据结构:
interface CaptchaSession {
sessionId: string; // 唯一会话ID
userId: string; // 用户标识
code: string; // 4位验证码
svg: string; // SVG图形验证码
timestamp: number; // 生成时间戳
originalContext: {
sessionKey: string; // 会话密钥
senderId: string; // 发送者ID
commandBody: string; // 命令内容
channel: string; // 消息渠道
to: string; // 目标用户
accountId: string; // 账户ID
toolName: string; // 工具名称
toolParams: any; // 工具参数
};
}
2. HTTP 服务器
监听 18800 端口,提供验证页面和 API。
端点:
GET /health- 健康检查GET /captcha/{sessionId}- 显示验证页面GET /captcha/{sessionId}?svg- 获取验证码图片POST /captcha/{sessionId}- 提交验证码
3. 插件钩子
使用 OpenClaw 的 before_tool_call 钩子拦截敏感工具调用。
敏感工具列表:
bashexecrunCommandcommandprocess
处理流程:
- 检查是否为敏感工具
- 提取命令内容(支持
command、cmd、input、args等参数) - 检查是否包含敏感关键词
- 检查用户是否已验证(5分钟内)
- 如未验证,生成验证会话并阻止执行
- 返回验证链接
验证码生成原理
验证码使用 svg-captcha 库生成 SVG 格式,包含以下特性:
- 随机数字:生成 4 位随机数字
- 干扰线:添加 2 条随机位置和颜色的干扰线(
noise: 2) - 字符变换:每个数字随机旋转、缩放、位移
- 彩色模式:支持彩色字符和干扰元素(
color: true) - 背景色:浅灰色背景
#f0f0f0 - 尺寸:150x50 像素
SVG 示例:
<svg width="200" height="80" xmlns="http://www.w3.org/2000/svg">
<!-- 背景渐变 -->
<rect width="200" height="80" fill="url(#bg)"/>
<!-- 干扰线 -->
<line x1="20" y1="10" x2="180" y2="70" stroke="#ff0000" stroke-width="2"/>
<!-- 干扰点 -->
<circle cx="15" cy="25" r="2" fill="#00ff00"/>
<!-- 数字字符 -->
<text x="40" y="50" font-size="32" transform="rotate(-10,40,50)">7</text>
<text x="80" y="50" font-size="32" transform="rotate(5,80,50)">2</text>
<text x="120" y="50" font-size="32" transform="scale(0.9)">3</text>
<text x="160" y="50" font-size="32" transform="translate(0,5)">9</text>
</svg>
安全特性
| 特性 | 说明 |
|---|---|
| 会话隔离 | 每个请求生成独立的 sessionId |
| 防重放攻击 | 验证后立即删除会话,无法重复使用 |
| 时间限制 | 验证码 300 秒过期,防止长期有效 |
| 验证有效期 | 通过后 300 秒免验证,平衡安全与便利 |
| 多用户支持 | 按 userId 分别管理验证状态 |
| 图形验证 | SVG 随机干扰,防止 OCR 识别 |
| 自动清理 | 定期清理过期的会话和验证状态 |
文件结构
extensions/image-captcha-auth/
├── index.ts # 插件主入口,注册钩子和回调
├── src/
│ ├── captcha-manager.ts # 验证码管理器
│ ├── server.ts # HTTP 服务器
│ ├── config.ts # 配置文件
│ ├── types.ts # 类型定义
│ └── captcha-manager.test.ts # 测试文件
├── openclaw.plugin.json # 插件配置
├── package.json # 依赖配置
└── README.md # 说明文档
依赖说明
插件依赖以下 npm 包:
svg-captcha- SVG 验证码生成库tsx- TypeScript 执行器(用于开发)
这些依赖已包含在插件目录的 package.json 中,无需在根目录安装。
API 端点
HTTP 服务器提供以下端点:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /health |
健康检查,返回 “OK” |
| GET | /captcha/{sessionId} |
显示验证页面(HTML) |
| GET | /captcha/{sessionId}?svg |
获取验证码图片(SVG) |
| GET | /captcha/{sessionId}?refresh |
刷新验证码(返回 JSON) |
| POST | /captcha/{sessionId} |
提交验证码验证(JSON) |
POST /captcha/{sessionId} 请求格式
{
"code": "1234"
}
POST /captcha/{sessionId} 响应格式
{
"success": true
}
GET /captcha/{sessionId}?refresh 响应格式
{
"success": true,
"remainingTime": 285
}
自定义配置
添加白名单用户
编辑 src/config.ts:
export const config = {
allowlistUsers: [
"admin@example.com", // 添加需要跳过验证的用户
"trusted-user",
],
// ...
};
添加敏感关键词
export const config = {
sensitiveKeywords: [
"rm",
"remove",
"delete",
"your-sensitive-keyword", // 添加自定义关键词
],
// ...
};
调整验证码有效期
export const config = {
timeout: 600000, // 验证码有效期:10分钟
verificationDuration: 600000, // 免验证有效期:10分钟
// ...
};
调整验证码难度
编辑 src/captcha-manager.ts 中的 generate 方法:
const captcha = svgCaptcha.create({
size: 4, // 验证码位数
noise: 2, // 干扰线数量
color: true, // 彩色模式
background: "#f0f0f0", // 背景色
width: 150, // 宽度
height: 50, // 高度
});
启用调试模式
export const config = {
debug: true, // 启用调试模式,输出更多日志
// ...
};
修改通知内容
编辑 index.ts 中的 setNotifyCallback 函数:
payloads: [
{
text: `✅ 验证成功!\n\n您的操作已获授权。`,
},
];
添加敏感工具(需要修改代码)
编辑 index.ts,在 sensitiveTools 数组中添加新的工具:
const sensitiveTools = [
"bash",
"exec",
"runCommand",
"command",
"process",
"your-custom-tool", // 添加自定义工具
];
故障排查
验证码无法打开
- 检查 HTTP 服务器是否运行:
curl http://localhost:18800/health - 检查端口 18800 是否被占用:
netstat -ano | findstr :18800(Windows)或lsof -i :18800(Linux/Mac) - 查看网关日志中的错误信息
- 确认插件已正确加载,日志中应显示
[image-captcha-auth] HTTP server running
验证后仍需验证
- 检查
verificationDuration配置是否正确 - 确认 userId 格式是否一致(使用 sessionKey 作为 userId)
- 启用
debug模式查看详细日志 - 检查验证时间是否已过期(5 分钟有效期)
通知未发送
- 检查
userId解析是否正确 - 查看
resolveOutboundTarget和deliverOutboundPayloads是否正常 - 检查消息渠道连接状态
- 启用
debug模式查看通知发送日志
验证码识别困难
- 调整
noise参数减少干扰线数量 - 增加验证码位数(
size参数) - 调整
width和height参数改变验证码尺寸 - 点击验证码图片可以刷新生成新的验证码
插件未生效
- 确认插件已安装到
extensions/image-captcha-auth目录 - 检查
openclaw.plugin.json配置是否正确 - 查看网关启动日志,确认插件已加载
- 确认使用的工具在敏感工具列表中
扩展建议
- 数据库持久化:将验证状态保存到数据库,支持多实例部署
- 验证码类型扩展:支持滑动验证、拼图验证等多种类型
- 验证历史记录:记录所有验证操作,用于审计
- 频率限制:限制验证尝试次数,防止暴力破解
- IP 白名单:为特定 IP 地址添加白名单,跳过验证
- 自定义验证页面:支持自定义验证页面的样式和文案
- 验证码音效:为验证码添加语音播报功能
开发调试
运行开发模式
cd extensions/image-captcha-auth
npm run dev
调试日志
启用 debug 模式后,插件会输出详细日志:
[captcha] Tool call detected: bash
[captcha] Extracted command from bash: rm -rf /tmp/test
[captcha] Command is sensitive, blocking
[captcha] User session:123 verified, allowing
[captcha] User session:123 verified, sending notification
[captcha] Notification sent successfully to session:123
更多推荐


所有评论(0)