gl0di/clawseccheck
GitHub: gl0di/clawseccheck
一款零依赖、纯本地的 OpenClaw AI agent 安全自检工具,通过启发式静态分析为配置评分并输出可执行的修复建议。
Stars: 4 | Forks: 0
🔍 为你自己的 OpenClaw agent 提供免费、本地、只读的安全自检。
免费 · 本地 · 只读 · 无需 API key · 你的数据永远不会离开你的设备
为你*自己*的 OpenClaw agent 提供的一键式安全自检。它会为你的设置评分
**A–F**,用通俗易懂的语言指出最紧迫的漏洞,并提供可直接复制粘贴的修复方案 —
此外还附带一个 **可分享的等级徽章**。
因为你是在自己的 agent 上运行它,所以不存在“扫描他人”的问题:无需
所有权证明,也没有法律灰色地带。
## 🔒 本地、只读,且诚实面对自身局限
ClawSecCheck **在本地以只读模式运行** — 没有网络调用、没有遥测,任何数据都不会
离开你的设备。它是一种启发式审计,因此对其能检查和不能检查的内容非常透明:
**诚实的局限(我们绝不会将这些隐藏在绿色分数背后):**
- **静态分析,未经运行时验证。** 发现的问题描述的是你的*配置*,而不是
实时的漏洞利用。结果会相应地进行标注。
- **`UNKNOWN` ≠ `PASS`。** 如果无法读取文件、无法解析配置或无法确定状态,
它会报告为 `UNKNOWN` 并排除在评分之外 — 绝不会默默标记为安全。
- **一些深度检查已在计划中,但尚未发布:** 脏输入动作门控和污点追踪
层(B27–B28)已在路线图上,已发布的 B33 版本门控目前仅植入了少量
经过核实的安全公告 — 其表格会随着新公告被验证而增长,目前还不是一个详尽的 CVE 数据库。
- **审查扫描器本身**(使用 `--vet` 指向 ClawSecCheck 自身的源码)会报告
*安全但有注意事项* — 安全工具必然会将攻击特征作为数据附带。
**发现了误报/漏报或令人困惑的地方?** 请在
提交一个 issue,并附上 `clawseccheck --json` 的输出
(它会隐去敏感的*值* — 仅显示键名/路径)以及你的 OpenClaw 版本。请勿
粘贴原始的敏感信息。
## ⚠️ 重要提示 — 不要信任任何人(包括此 skill)
OpenClaw skills **并未被沙盒化**:已安装的 skill 会以你 agent 的完整
权限运行。ClawHavoc 活动向 ClawHub 投毒,植入了**数百个恶意 skills**,
用于窃取凭证和加密钱包 — 区区一行 markdown 就能隐藏
`curl http:// | bash`。
因此,在下载、安装或使用**任何** skill(包括这一个)之前:
1. **阅读源码** — 它们都是纯文本。如果你看不出它的作用,就不要运行它。
2. **让你的 agent 替你分析** — 要求 OpenClaw 在启用该 skill *之前*,审查其 `SKILL.md`
和脚本中是否存在 shell 执行、凭证访问、粘贴托管站点上传以及混淆的
(base64) payload。ClawSecCheck 就是通过 `--vet ` 实现这一点的。
3. **锁定已知版本**,优先选择已签名 / VirusTotal 检测安全的 skills,如果你曾怀疑某个
skill 接触过某些凭证,请立即轮换该 skill 可能触及的所有密钥。
ClawSecCheck 践行了这一点:它是开源的、零依赖的、只读的,而且它的 **B13** 检查
正是对你*已经*安装的 skills 进行此类审查。信任是通过可读性赢得的 —
所以,请亲自去阅读它。
## 🤔 为什么还要再来一个审计工具?
内置的 `openclaw security audit` 以及像 Trent/ClawSec 这样的工具都很不错 — 但是:
- 原生审计**不会检查你的 bootstrap 文件内容**
(`SOUL.md`, `AGENTS.md`, `TOOLS.md`):它们会作为*受信任的上下文*被注入到系统 prompt 中,且没有任何验证。而 ClawSecCheck **确实**会检查它们是否存在容易引发 prompt 注入的
指令(对应我们的检查 **B6**)。
- ClawSecCheck 是 **100% 本地化**的 — 不需要 API key,也不会传输任何内容(Trent 会上传你的配置;
而原生工具仅限 CLI 使用)。
- 它以可分享的 **分数 + 等级 + 致命三角组合比率**为核心亮点,你可以将其发布到
社区 — 而且完全不会暴露你实际的安全发现。
## 🔬 它检查的内容
- **致命三角组合** (不可信输入 × 敏感数据 × 出站操作 — 保持在 3 项中的 ≤2 项)
- 网关暴露与通道认证、明文密钥、最小权限、执行沙盒、
plugin/skill 供应链完整性、bootstrap 文件注入面、记忆投毒、
人工审批、密钥泄露/隐去、TLS、本地优先/模型卫生。
- **B13 — 已安装 skill / plugin 审查:** 扫描你下载的(非自己制作的)skills 的*内容*,
以检测 ClawHavoc 恶意软件家族,包括 base64 隐藏的 payload。从
v0.21 版本开始,它还会运行静态 **Python AST** 扫描(使用标准库 `ast`,仅进行解析 — 绝不执行代码),这可以捕获正则表达式遗漏的混淆行为 — `exec(base64.b64decode(...))`, `getattr(os,"sys"+"tem")(...)`,
`__import__("os").system(...)` — 以及嵌入在第三方
skill 文本中的 prompt 注入 / 对用户隐藏的指令,并且 (v0.23) 引入了**污点追踪**,可以标记流入网络接收端(“读取敏感文件 → 发送出去”)的凭证**文件**内容
(`~/.ssh/id_*`, `.aws/credentials`, keychain, wallet, …)。污点源仅限凭证文件,不包括环境变量,因此合法的“读取
`OPENAI_API_KEY`,作为 auth header 发送”模式永远不会被标记。(AST 仅支持 Python;JS/shell 仍依赖于
正则表达式引擎。)
- **B14 — 出站流量面:** agent 可以访问的外部资源(通道、外部 skills、工具)。
- **B15 — MCP server 信任**边界。
- **B16 — 威胁监控:** 你是否真正建立了监控/检测机制。
- **B17 — 自主性 / 心跳:** agent 是否会自主行动,以及是否可能被不可信输入所操纵。
- **B18 — 子 agent 委派:** 衍生出的子 agent 是否能在未经审批的情况下使用提权/执行工具。
- **B45 — 单 agent 权限隔离 (证明层):** A1 会将整个设置扁平化为单一的
能力面;B45 会读取经过证明的 agent 名单 (`--attest`, `agents: [{name, tools}]`) 并
检查是否有*单一*的 agent 独自掌握了三角组合的全部三项要素。OpenClaw 配置中没有
针对单个 agent 的工具白名单,因此这需要自我报告 — 如果没有则为 `UNKNOWN`,属于建议性质 (`ATTESTED`,
不参与评分)。PASS 意味着“没有单个 agent 构成完整的三角组合” — 这是一个必要条件,**但并非**
保证:运行时数据流和委派图不在检查范围内。
- **B46 — 多 agent 三角组合暴露:** 仅针对配置的提醒 — 可衍生的子 agent **加上**全局
三角组合 **加上**没有执行审批门控。最高级别为 WARN(永远不会新增 FAIL)。
- **B47 — 跨 agent 三角组合重组 (证明层):** 即使没有单个 agent 构成三角组合,
它也可以跨委派进行重组(一种*混淆代理*):一个不可信输入的 agent 驱动一个
敏感数据 agent 和一个出站 agent。读取经过证明的 `delegation: [{from, to, returns}]`
图;`returns` 层级决定了可利用性 — 返回 `schema` (类型化) 是一堵**墙**,
可阻断该通道(PASS,附带非运行时验证的警告),而 `raw`/`filtered`/`unknown`
则会将其传递下去(WARN)。如果没有 `--attest` 则为 `UNKNOWN`。`RISK-11` 描述了该攻击链。静态检查范围仍不包含运行时数据流。
- **B19 — 静态数据:** 可被用户组/其他用户读取的 memory/log 目录(对话数据 / PII 泄露)。
- **B20–B24 — agent 行为:** 身份/记忆文件的写保护、工具输出信任边界、
自我修改风险、绕过审批指令,以及深度的 MCP server 安全加固。
- **B30 — 发送者身份强度:** 标记 `channels..dangerouslyAllowNameMatching`
(白名单基于可变的显示名称 — 只需重命名即可轻松绕过) 和
`channels.telegram.includeGroupHistoryContext="recent"` (不可信的群组历史被作为上下文注入)。
- **B32 — 控制面变更可达性:** 标记通过 `gateway.tools.allow` 暴露在
HTTP gateway 上的控制面工具 (`cron`, `config.apply`,
`update.run`, `sessions_spawn`, `sessions_send`, `gateway`) — 无需进一步提权即可完全接管 agent。
- **B38 — 浏览器 / SSRF 暴露:** 标记 `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`
(云元数据 IP 访问 / 通过 169.254.169.254 窃取凭证) 和 `browser.noSandbox`
(无 OS 隔离的无头浏览器);当没有 `hostnameAllowlist` 限制出站流量时发出警告。
- **B48 — 危险的紧急突破覆盖:** 一个基于事实的 OpenClaw `dangerously*` /
`allowUnsafe*` 开关注册表,文档中注明“保持禁用”。当沙盒逃逸
(`sandbox.docker.dangerouslyAllow{ContainerNamespaceJoin,ExternalBindSources,ReservedContainerTargets}`)
或控制面绕过认证 (`gateway.controlUi.dangerouslyDisableDeviceAuth`) 标志被激活时,标记为 **FAIL**;
对于其余项(禁用 webhook 签名、host-header 源回退、外部嵌入、
real-IP 回退、`allowUnsafeExternalContent`、基于通道/plugin 的专用网络访问、额外的
node 命令),标记为 **WARN**。默认/缺失 = 完美的 PASS(在默认配置下零误报)。
- **B39 — 会话可见性 / 跨用户对话泄露:** 标记 `session.dmScope="main"`
(所有 DM 对等端共享一个会话 — 导致跨用户污染) 以及 `tools.sessions.visibility`
为 `"agent"` 或 `"all"` (跨会话对话读取)。
- **B26 — 不可信上下文暴露:** 标记 `channels..contextVisibility="all"` (这是
OpenClaw 的默认值),在这种情况下,来自非白名单发送者的引用/线程/历史文本会被作为上下文注入到
模型中 — 形成 prompt 注入面;建议设置为 `allowlist`/`allowlist_quote`。
- **B33 — 已知漏洞版本门控:** 将 `meta.lastTouchedVersion` 与维护中的
OpenClaw 公告表进行比对(目前包含 GHSA-g8p2-7wf7-98mq,已在 `2026.1.29` 修复);未知版本为
`UNKNOWN`,永远不为 `PASS`。
- **B41 — 凭证爆炸半径:** 盘点 agent 可达的凭证面(`auth.profiles.*`,
gateway token),并在其与不可信入口 + 出站工具同时存在时发出警告。
仅报告提供商名称 + 数量 — 绝不会泄露账户/邮箱或 token 值。
- **B31 — 有效工具绕过:** 检测 OpenClaw 中存在的隐患,即 `tools.deny: ["write"]` 并不会
拒绝 `apply_patch`/`exec` — 这种被认为是安全的限制实际上仍然允许文件修改;检查范围涵盖
全局、`toolsBySender` 以及各 agent 的拒绝列表。建议使用 `group:fs` 或完整的拒绝列表。
- **B42 — skill/plugin 安装时策略:** 安装时的供应链风险(本身不一定属于恶意软件)—
`package.json` 的 `pre/postinstall` 钩子会在安装时**以及每次自动更新时**运行代码
(在非沙盒环境中,拥有该 agent 的权限),以及**全局可写的 skill 目录**(任何本地
用户都可以投放一个会被 agent 加载的 skill)。最高级别为 WARN,永远不触发 FAIL;是对 B25 (锁定版本) 和 B13
(内容审查) 的补充。
- **B50–B54 — 主机监控姿态:** 将视角从 agent 扩展到*运行它的主机* —
是否有人在它?采用只读的、仅限文件系统的检测方式(无子进程,无网络调用)来发现主机
防御监控工具:**B50** 网络监控 / IDS (Suricata, Zeek, Snort, Little Snitch,
Sysmon),**B51** 主机审计 / syscall 日志 (auditd, OpenBSM, Sysmon),**B52** 文件完整性
监控 (AIDE, Tripwire, osquery),**B53** 端点保护 / EDR (Wazuh, CrowdStrike,
ClamAV, Defender, Santa),**B54** 主机防火墙 (ufw, firewalld, nftables, macOS ALF, Windows
Firewall)。严重性为 LOW,**永远不会触发 FAIL**:缺少监控工具仅当 agent 处于
高权限状态时才发出 WARN,否则为 PASS;任何无法通过只读方式确定的均标记为 `UNKNOWN`。在无需运行命令即可读取的情况下,它能区分*已启用*和*仅已安装*。
- **B43 / B44 — 能力爆炸半径 (证明层):** 静态扫描仅读取配置文件;
它无法看到 agent *真实的*工具/动词清单 — 配置只是将工具*名称*列为不透明的
字符串。证明层弥补了这一点:`--ask` 会生成一个模板,由正在运行的 agent 用其自身的
真实数据进行填充,然后通过 `--attest ` 反馈回来。**B43** 根据爆炸半径对持有的动词进行分类 —
`EXEC` (bash/shell/exec — 影响最广:包含了出站+破坏性操作),
`MAILBOX_CONFIG` (自动转发/过滤/委派 — 一种持久的隐蔽通道),
`DESTRUCTIVE` (永久删除/清除),`EGRESS` (发送/转发/发布),`REVERSIBLE`
(搜索/获取/草稿/标记)。一个仅具备可逆操作能力的工具集会*通过检查*(向外转发窃取数据和删除证据在物理上是不可能的);
而未经审批即可触发的高危动词则会导致*不通过*。**B44**
会将自我报告与配置中的 `tools.allow` 进行交叉检查,并标记出配置
已授予但 agent 遗漏未报的高危动词(配置漂移 / 盲点 / 掩盖行为)。这两者的置信度均处于 `ATTESTED` 级别 —
自我报告的证据效力弱于配置事实,因此它们仅作为建议,且绝不会互相覆盖。
只读与内省:agent 只报告它拥有什么,绝不会为了测试而去*执行*某个动词。
证明层的 `paths` 块还可让 agent 指引 B20/C5 去查找其身份/记忆
文件以及 OpenClaw 安装路径的真实位置 — 仅用于发现:agent 提供*位置*,但引擎依然会自行
对该路径执行 `stat()`,因此那些权限相关的发现结果依然保持完整的文件系统状态强度(而不是 `ATTESTED`)。
- **B20 / C5 — 静态写保护:** B20 会标记位于 home 根目录**以及**工作区目录中,可被用户组/其他用户写入的 bootstrap/身份/记忆
文件 (`SOUL.md`/`AGENTS.md`/`TOOLS.md`/`MEMORY.md`);
C5 会标记可被用户组/其他用户写入的 openclaw 二进制文件目录、其安装树祖先节点(例如 npm
package 根目录 — 一种二进制文件替换攻击向量),以及位于其前方的、可写的 PATH 目录。像
`/tmp` 这样的粘滞目录(sticky dirs)将被豁免(sticky bit 会阻止跨所有者的替换)。
- 此外,还会为你运行并整合平台自带的 **`openclaw security audit`**。
**映射至 OWASP。** 每一项检查都标记了对应的 **OWASP Top 10 for LLM Applications (2025)**
类别(在 `--json` 中以 `"owasp": [...]` 形式针对每条发现展示),并且这些检查还映射到了
特定于 agent 的 **OWASP Agentic (ASI)** 威胁类别 — 如工具滥用、多 agent 身份/权限
滥用、不安全的 agent 间通信、级联爆炸半径 — 这些都是应用代码审查者通常难以
察觉的。完整矩阵请参阅 [`docs/THREAT_COVERAGE.md`](docs/THREAT_COVERAGE.md)。
## 🧩 包含内置审计
非技术用户永远不会打开终端去运行 OpenClaw 自带的
`openclaw security audit`。因此,ClawSecCheck 会**替你**运行它(只读模式),并将其
发现整合到同一份通俗易懂的报告中 — 只需一个按钮即可同时展示 ClawSecCheck 的检查结果
*以及*平台原生的审计结果。原生审计的发现会被展示出来,但**不会**混入
ClawSecCheck 的评分中(以保持评分的确定性)。可以使用 `--no-native` 禁用。
## 🛡️ 信任 / 来源
ClawSecCheck 是**开源且零依赖的(仅使用 Python 标准库)**。其自带的检查是
**只读且离线的** — 它们仅读取 `~/.openclaw/openclaw.json` 和你工作区中的
bootstrap markdown 文件,并**不发起任何网络调用**。它绝不会触碰你的 OpenClaw 配置或
数据,并且**任何信息都不会离开你的设备**。默认情况下,它唯一会写入的内容是向**私有的、仅限所有者访问的**本地分数历史记录 (`~/.clawseccheck/history.jsonl`) 中添加一行记录,
以便你随时追踪自己的等级变化 — 可以使用 `--no-history` 退出此功能。其他所有内容仅在你主动
要求时才会写入:报告文件 (`--save`)、`--monitor` 快照 (`~/.clawseccheck/state.json`)、徽章
(`--badge`)、HTML/SARIF (`--html`/`--sarif`) 或日志 (`--log`)。
它**唯一**可能运行的外部命令也是你自己的、且已固定为只读模式的命令:
```
openclaw security audit --json
```
不使用 shell,绝不运行 `--fix`,并设有超时限制;可以使用 `--no-native` 完全跳过。整个
源码都位于 [`clawseccheck/`](clawseccheck/) 中 — 在信任它之前,请先阅读。在 ClawHavoc
恶意 skill 浪潮之中,一个审计 skill 应当证明自身的安全性;这一个做到了。
## 🚀 安装与运行
```
openclaw skills install clawseccheck # from ClawHub (the slug is unique)
openclaw skills install git:gl0di/clawseccheck # or straight from GitHub
# 然后请求您的 agent:“audit my OpenClaw setup with clawseccheck”
```
ClawHub 上的 Skill 主页:****。
或者将其作为独立的 CLI 安装(零依赖):
```
pipx install git+https://github.com/gl0di/clawseccheck # or: pip install .
clawseccheck --home ~/.openclaw # then just `clawseccheck`
python -m clawseccheck # also works
```
或者直接运行打包好的脚本(Linux/macOS):
```
python3 audit.py # human report + shareable card
python3 audit.py --json # machine-readable
python3 audit.py --card # just the badge
python3 audit.py --ascii # plain output (no unicode icons/box)
python3 audit.py --home ~/.openclaw
```
在 **Windows** 上请使用 `python`(或 `py`);该脚本会自动检测无法渲染
unicode 的控制台并回退到 ASCII 模式,或者使用 `--ascii` 强制执行:
```
python audit.py
py audit.py --card --ascii
```
跨平台支持:纯 Python 标准库实现,基于 pathlib 的路径处理,在
Windows 上会跳过 POSIX 文件权限检查(NTFS 使用 ACLs),并且所有输出都有对应的 ASCII 回退支持。
## 🔄 更新
OpenClaw 会记住 skill 的来源,因此用户可以通过更新来获取你的最新版本:
```
openclaw skills update clawseccheck # pull the latest from its source (Git/ClawHub)
clawhub update --all # update every installed skill
```
(或者重新运行安装命令。)一个自动更新程序 skill 或位于
`~/.openclaw/openclaw.json` 中的 `update.auto.enabled` 可以按计划进行更新。由于 skills 会以 agent 的
完整权限运行,因此恶意的*更新*是一种真实的供应链风险 — 所以这里的每一次发布都打了标签,
并且源码是公开可读的,方便你在更新**之前**进行审查。对于任何安全敏感的内容,优先选择
审查/锁定特定标签,而不是盲目地自动更新。
**过期提醒(离线)。** 过时的安全扫描器本身就是一种风险,因此默认报告
可能会打印一行“你的本地构建可能已过期”的通知。这完全是在**离线状态**下进行的 — 它只将
本地时钟与内置的构建日期进行比对,并读取一个可选的本地提示文件
`~/.clawseccheck/latest.json`(该文件可由你的分发层或 agent 写入)。ClawSecCheck **绝不
通过网络检查自身的更新**(这会破坏其零网络调用的承诺,否则它就必须
将自身标记为异常)。真正的“是否有新版本?”查询应该交由你的包管理
工具或你的 agent 来完成 — 请参阅 SKILL.md 中的“Keeping ClawSecCheck current”部分。可以使用
`--no-update-notice` 或 `CLAWSECCHECK_NO_UPDATE_NOTICE=1` 隐藏该通知;在每次更新后,请使用
`--verify-self` 验证引擎。
## 🧭 引导模式
当你在 OpenClaw 中运行 ClawSecCheck 时,agent 会以对话的方式引导你完成整个审计
过程 — 你完全不需要了解任何命令参数。在每次默认运行之后,ClawSecCheck 都会打印出一个简短的
**“下一步建议”**模块:一份针对*你的*发现结果量身定制的优先级最高的后续步骤列表,
并附带每一步的确切执行命令。
同样的列表还可以通过另外两种方式获取:
```
python3 audit.py --next # print the next-steps block only (after running the audit)
python3 audit.py --json # includes a "next_actions" array in the JSON envelope
```
这些建议是由你的实际检查结果驱动的 — 未解决的 FAIL 发现会优先展示 `--prompts`;
未经过审查的第三方 skills 会提示使用 `--vet`;未检测到监控工具会提示使用 `--monitor`;
以此类推。当没有紧急事项时,该模块会如实告知,并建议你进行较轻量级的后续操作
(趋势追踪、等级分享)。
**ClawSecCheck 绝不会应用任何修复或更改你的配置。** 对于每一项未解决的发现,`--prompts`
都会为你提供一个现成的、可复制粘贴的 prompt,以便你交给你的 agent(或自行应用);
更改的决定权在于你。所有操作均在本地完成。
**`--fix` — 可直接粘贴的修复方案。** 针对你当前未通过/警告 (FAIL/WARN) 的发现,打印出精确且可直接复制粘贴的修复方法:
安全的 shell 命令(如 `chmod 600 ~/.openclaw/openclaw.json`)和
配置指导(`set tools.exec.mode → "ask"`)。它**仅作输出展示** — ClawSecCheck 不会
应用任何更改;你需要自行审查并运行。配置修复会以*将此点分路径设置为此值*的指导形式提供(因此
你需要自行编辑 `openclaw.json`),而绝不会给你一个直接粘贴覆盖的 JSON 数据块,以免
覆盖你其他的键值。每条发现在 `--json` (`"remediation"`) 和 SARIF (`fixes`) 中也均会提供。
## 📋 如何获取报告
当你在 OpenClaw 中运行该 skill 时,agent 会执行 `audit.py`,捕获其输出,
并**直接在聊天界面中**展示给你 — 无需终端,也无需配置。你会看到:
1. 你的 **分数 / 等级 / 致命三角组合 (Lethal Trifecta)** 比率,
2. 用通俗语言列出的**修复列表,最紧急的排在最前**,以及
3. 一张**可分享的卡片** — 包含等级、分数和致命三角组合比率,可以安全地发布(发现结果依然保持
私密;`--badge` 会将相同的等级和分数输出为 SVG 格式)。
如果想保留副本,可以添加 `--save report.txt`,ClawSecCheck 会将完整报告写入该文件
(仅在你主动要求时写入)。如果需要自动化处理,`--json` 会提供机器可读的结果。
## 📡 威胁监控
两个互补的方面:
**B16 — 你是否建立了监控?** ClawSecCheck 会检查你是否设置了威胁
监控/检测机制 — 如果一个 agent 完全没有监控,那么在被入侵时它将无法向你报警。B16 会寻找
监控 skill/plugin(如 ClawSec、`openclaw-security-monitor` 等)或监控/报警
配置;如果未发现相关配置,它会向你发出警告,并告诉你如何添加。
**`--monitor` — Agent 监视。** 实现*监控*的一种方式:按计划重新进行审计,并针对
**发生变更**的内容(**按严重程度排序**)发出警报 — 比如新安装或被修改的 skill、`SOUL.md` 发生漂移、
分数下降、某项检查从 PASS 变为 FAIL、**新连接的 MCP server、新的通信通道、gateway 变得
暴露在网络中,或者是某个主机监控工具消失了**。每次运行都会将这些变更追加到一个私有的本地
日志中(`~/.clawseccheck/events.jsonl`,仅限所有者访问,绝不上传);使用
`--watch-log` 查看时间线。(漂移检测在升级时是安全的:旧的快照绝不会产生虚假的
“新连接”警报。)
```
python3 audit.py --monitor # first run = baseline, then alerts on changes
python3 audit.py --monitor --state ~/.clawseccheck/state.json
```
通过 OpenClaw 的心跳或 cron 功能进行定时调度;当警报触发时,让你的 agent 发消息通知。
它会在 `~/.clawseccheck/state.json` 中存储一个小型的快照。(这是一种定时重新审计 + 漂移
检测机制 — 并非实时的运行时 IDS;那种更重的模型被刻意排除在范围之外了。)
## ⛓️ 最高风险路径
除了单独的检查项之外,ClawSecCheck 还运行一个**风险引擎**,用于寻找危险的
*组合* — 即两个或多个同时出现的属性导致系统被攻破时变得极具灾难性,
或使得攻击变得轻而易举的能力链条。
它能检测到 11 种攻击链(RISK-01 到 RISK-11):
| ID | 严重程度 | 攻击链 |
|----|----------|-------|
| RISK-01 | CRITICAL | 不可信发送者 (开放的 DM/群组) → 执行/写入/提权工具 → 主机/文件系统 |
| RISK-02 | HIGH | 不可信输入 → 可达的敏感数据 → 出站/执行工具 (致命三角组合) |
| RISK-03 | HIGH | 不可信入口 + 无执行沙盒 → 直接在主机上执行/写入 |
| RISK-04 | HIGH | 可变的 agent 身份 (名称匹配) → 提权/执行工具 → 权限提升 |
| RISK-05 | HIGH | 浏览器 SSRF 访问内部网络 → 窃取 secrets/credentials → 数据渗出 |
| RISK-06 | CRITICAL | 开放的/不可信的面 → 控制面 endpoint → 完全接管 agent |
| RISK-07 | HIGH | 执行/写入工具 (无审批门控) → 可写的 bootstrap/身份文件 → 持久化控制 |
| RISK-08 | MEDIUM | 多用户通道 → 共享会话 (`dmScope="main"`) → 跨用户数据泄露 |
| RISK-09 | CRITICAL | 恶意的已安装 skill (B13 不通过) → 可达的 secrets/数据 → 出站流量 → 数据渗出 |
| RISK-10 | MEDIUM | 不可信输入 → agent 可在主机上执行/写入 → 无主机检测 (IDS/audit/FIM/EDR) → 数据泄露将悄无声息 |
| RISK-11 | HIGH | 跨 agent 三角组合重组 (混淆代理):不可信输入 agent → 驱动敏感数据 agent → 驱动出站 agent (通过非墙体的委派边缘) |
每条攻击链**仅在存在明确证据支持每一个环节时才会触发** — 绝不会基于
缺失或 UNKNOWN 的数据凭空捏造攻击链,因此发现结果是受证据限制的,这有助于保持较低的误报率 —
但这依然是启发式审计,并非绝对的安全保证;仍需进行人工审查。风险
引擎不会更改确定性的 A–F 评分;它会单独展示,以便你能够一目了然地看到
最坏情况下的路径,而不会导致分数虚高。
```
python3 audit.py --risk-paths # print the highest-risk chains section only
python3 audit.py --json # includes a "risk_paths" array in the JSON envelope
```
当任何攻击链触发时,`--risk-paths` 的输出也会被附加到默认报告的末尾。
## ⚙️ CI / 自动化
```
python3 audit.py --sarif results.sarif # write SARIF 2.1.0 locally (for GitHub Code Scanning upload step)
python3 audit.py --fail-under 70 # exit 1 if score < 70 (use in CI pipelines)
python3 audit.py --exit-code # exit 1 if any unsuppressed FAIL finding
```
SARIF 文件将写入你选择的路径 — ClawSecCheck 绝不会将其上传到任何地方。
`--fail-under` 和 `--exit-code` 在省略时不会更改默认的退出代码 (0),
从而保持向后兼容性。
## 🧰 更多工具
**快速 CLI 参考手册**(针对你的配置,所有的参数都是在本地以只读方式运行的):
| 需求 | 命令 |
|---|---|
| 人类可读报告 | `clawseccheck` |
| JSON / SARIF 输出 | `clawseccheck --json` · `clawseccheck --sarif results.sarif` |
| 可直接粘贴的修复方案 | `clawseccheck --fix` |
| 最高风险攻击链 | `clawseccheck --risk-paths` |
| 安装前审查 skill | `clawseccheck --vet ./skill` |
| 审查已连接的 MCP servers | `clawseccheck --vet-mcp` |
| 主动注入自测 | `clawseccheck --canary` · `clawseccheck --redteam` · `clawseccheck --dryrun` |
| 监控漂移 / 查看时间线 | `clawseccheck --monitor` · `clawseccheck --watch-log` |
| 证明模板 / 反馈结果 | `clawseccheck --ask` · `clawseccheck --attest attest.json` |
| 可分享的卡片 / SVG 徽章 | `clawseccheck --card` · `clawseccheck --badge badge.svg` |
| 趋势与百分位数 | `clawseccheck --trend` · `clawseccheck --percentile` |
| 接受某项发现 (显示被抑制项) | 编辑 `.clawseccheckignore` · `clawseccheck --show-suppressed` |
| 跳过原生审计 / 主机监控姿态 | `clawseccheck --no-native` · `clawseccheck --no-host` |
| 禁用本地历史记录 / 过期提醒 | `clawseccheck --no-history` · `clawseccheck --no-update-notice` |
| CI 门控 | `clawseccheck --fail-under 70` · `clawseccheck --exit-code` |
| 希伯来语 (RTL) 输出 | `clawseccheck --lang he` |
| 验证引擎自身 | `clawseccheck --verify-self` |
```
python3 audit.py --next # print the "What you can do next" guidance block only
python3 audit.py --vet ./some-skill # vet a skill (dir or SKILL.md) BEFORE installing it
python3 audit.py --vet ./some-skill --json # same, machine-readable (verdict + findings); --sarif PATH for CI
python3 audit.py --vet-mcp # vet connected MCP servers for supply-chain risk BEFORE trusting them
python3 audit.py --canary # active prompt-injection self-test (battle-tested)
python3 audit.py --redteam # a multi-scenario adversarial payload suite (incl. tool-poisoning, MCP-response injection, memory-poisoning, multi-agent, approval-bypass, dirty-to-exfil)
python3 audit.py --dryrun # runtime behavioral test (fake secret + fake tools; sources: email, web, MCP response, memory, subagent)
python3 audit.py --badge badge.svg # write a shareable SVG grade badge
python3 audit.py --html report.html # standalone HTML report (private — owner view)
python3 audit.py --verify-self # SHA-256 of ClawSecCheck's own source (anti-tamper)
python3 audit.py --prompts # a copy-paste "ask your agent to fix it" per finding
python3 audit.py --lang he # Hebrew report (right-to-left); default auto-detects locale
python3 audit.py --trend # print local score trend (stored in ~/.clawseccheck/history.jsonl)
python3 audit.py --percentile # show where your score sits vs. an offline reference profile
python3 audit.py --history ~/.clawseccheck/history.jsonl # custom history file path (default shown)
python3 audit.py --verbose # INFO-level log to stderr (secrets redacted)
python3 audit.py --debug # DEBUG-level log to stderr (secrets redacted)
python3 audit.py --log audit.log # also write log to a local file
```
- **`--next`** 会单独打印出“下一步建议”指导模块 — 它会先运行审计,
然后仅显示按优先级排序的后续步骤列表。内容与附加在
默认报告末尾的模块相同;如果你不想重新阅读完整报告,而是只想再次查看建议,这个命令会很有用。
- **`--vet PATH`** 会在你安装某个 skill *之前*,对其运行 B13 恶意软件扫描(可以指向一个已下载的
文件夹或 `SKILL.md`;如果是一个 URL,请先克隆,然后再审查本地副本)。判定结果为:
SAFE / SUSPICIOUS / DANGEROUS。添加 `--json` 可获得机器可读的判定结果及具体发现(不提供分数 —
因为审查并不是一种参与评分的审计),或者使用 `--sarif PATH` 输出 SARIF 文件以供 CI / 代码扫描使用;
当结果为 SUSPICIOUS/DANGEROUS 时,退出代码为 `1`,因此可以通过 `--vet … || fail` 来对安装流水线实现门控。
- **`--vet-mcp`** 用于在你信任它*之前*,审查每一个在 `mcp.servers.*` 下注册的 MCP server 的供应链风险。
它会标记未锁定版本的安装 (`npx @latest`,未版本控制的包)、`curl|sh`
引导程序、明文 HTTP 远程传输、环境变量密钥透传,以及过于宽泛的
OAuth scopes。每个 server 的判定结果为:SAFE / SUSPICIOUS / DANGEROUS。完全在本地且只读运行 — 不会进行
网络调用,也不会进行写入。针对的是 agent 供应链中的头号缺口:大多数工具只审查你的 skills,
却忽视了接入 agent 的 MCP servers。
- **`--canary`** 会发出一个隐藏在看似不可信内容中的良性注入指令;将其喂给你的
agent — 如果 agent 复述了该 token,则说明它遵从了注入指令 (**VULNERABLE**),否则为
**RESISTANT**。这是对被动检查的一种生动的“实战检验”补充。
- **`--badge PATH`** 会为你的 README / 帖子生成一个 shields 风格的 SVG(仅包含等级和分数)。
- **`--prompts`** 会将每一条发现转化为一个现成的 prompt,你可以粘贴给 agent 让它进行修复。
- **`--trend`** 会将当前的审计结果记录到一个仅限本地追加的历史文件中,并打印出
带有每次运行趋势箭头的过往分数表。历史记录仅保存在你的本地设备上。
- **`--percentile`** 会将你的分数与内置的离线参考样本进行比较 — 无需网络,
也没有遥测数据。
- **`--verbose` / `--debug` / `--log PATH`** 会激活结构化的本地日志记录。配置值中
可能包含敏感信息的部分在写入前会被隐去(践行 ClawSecCheck 自身的 B9/B10 检查理念)。
## ✅ 基准管理 (接受发现结果)
审查过某条发现并认定其可以接受?只需将其添加到 `~/.openclaw/.clawseccheckignore` 中即可 —
每行一条记录,可以是检查 id(如 `B14`),也可以是发现的指纹(如 `B14:ab12cd34`,可通过
`--show-suppressed` 查看)。被抑制的发现结果将从**分数**、**报告**以及
**监控**警报中剔除 — 这样重新运行和使用 `--monitor` 时就不会再对你已经接受的问题进行提示了。
```
# ~/.openclaw/.clawseccheckignore
B14 # accept the egress-surface advisory
B12:1a2b3c4d # accept one specific local-model finding
```
## 📊 评分机制
加权通过率 (CRITICAL=10, HIGH=6, MEDIUM=3, LOW=1)。**诚实的硬性上限:** 任何未解决的
CRITICAL 级别问题会将分数上限锁定在 49 分,任何未解决的 HIGH 级别问题锁定在 79 分 — 你绝不可能在存在严重
漏洞的情况下展示出“A”级。等级划分:A 90+ · B 80–89 · C 70–79 · D 50–69 · F <50。可分享的卡片**仅显示
等级 + 分数 + 三角组合比率 — 绝不会显示具体的发现结果**(分享结果绝不能等于向攻击者奉上你的漏洞图谱)。
## 📐 公共 API 与稳定性
自 **1.0.0** 版本起,以下内容属于**冻结契约**:打破它需要进行**主版本号**
升级 (SemVer)。该冻结是在证明层稳定后、经历过对抗性审查,并且经过了四次实地
测试(其中的每一项发现都被修复或刻意记录在案)后进行的 — 针对真实配置环境,没有出现任何硬性误报。
**冻结契约 (打破这些 → 主版本号升级):**
- **CLI 参数**及其文档定义的含义 (`--json`, `--sarif`, `--card`, `--monitor`,
`--fail-under`, `--exit-code`, …)。
- **`--json` schema:** 顶层的 `score`, `grade`, `capped`, `raw_score`, `trifecta`,
`findings[]`, `next_actions[]`;以及每条发现的 `id`, `title`, `severity`, `status`, `detail`,
`fix`, `framework`, `confidence`, `evidence`。
- **SARIF 2.1.0 输出**格式 (规则 id = 检查 id;包含 `properties.confidence` + `.evidence`)。
- **公共 Python API:** `clawseccheck.audit(...) -> (ctx, findings, ScoreResult)` 以及
`Finding` 字段名。
- **检查 ID** (`A1`, `B1–B54`, `C3–C5`, `RISK-01..10`):一旦发布,其 id 的含义将保持不变。
- **状态 / 置信度词汇表:** `PASS|WARN|FAIL|UNKNOWN`, `HIGH|MEDIUM|LOW|ATTESTED`。
- **评分区间:** A 90+ · B 80–89 · C 70–79 · D 50–69 · F <50;`UNKNOWN` 绝不参与计分;建议性
检查 (`scored=False`) 绝不影响等级评定。
**在 1.x 版本中明确作为实验性的内容(可能会在不进行主版本号升级的情况下发生更改,这是设计使然):**
- **证明层 (attestation layer):** 包含 `clawseccheck-attest/1` 自我报告 schema(注意其中的 `/1` —
它是明确标记了版本号以便演进的)、`--ask`/`--attest` 流程、B43 的 **动词→爆炸半径
分类法**,以及 B44。`ATTESTED` 置信度级别的存在正是为了准确标记这一点:自我报告
弱于配置事实,仅具建议性,且绝不会覆盖配置事实。如果现在就冻结这一最新功能面将导致过度承诺,
因此在该标签下它将保持灵活性,直到获得更广泛的实际应用验证。
## 🚦 状态
当前发布版本 **v1.8.0** — 公共 API 契约自 **1.0.0** 版本起已冻结(破坏性的
CLI / `--json` / SARIF 更改需要升级主版本号)。只读检查包含
A1/B1–B26/B30/B31/B32/B33/B38/B39/B41–B44/B48/B50–B54/C3–C5 (包括写保护、
自修改、绕过审批、深层 MCP、更新/版本锁定规范、发送者身份强度、
控制面可达性、浏览器/SSRF 暴露、会话可见性/跨用户泄露、一套
**主机监控姿态 (Host Watch Posture)** 环 — 即运行 agent 的主机是否处于监控之下:网络 IDS、主机
审计、文件完整性、EDR 以及主机防火墙 — 以及一个**证明层** (`--ask`/`--attest`,
附带引导式询问协议,让 agent 自行构建报告;`--attest -` 读取 stdin),
用于从 agent 自身的自我报告中对能力层面的爆炸半径进行分类:B43 危险动词
清单、B44 自我报告 ⇄ 配置漂移),
已安装 skill 的恶意软件审查、基准抑制 + 治理、合并内置的
`openclaw security audit`、主动注入测试 (`--canary`/`--redteam`)、运行时
空转测试工具 (`--dryrun`)、HTML 报告、自完整性验证 (`--verify-self`)、可通过 pip/pipx 安装的
CLI — 根据外部安全审查进行了强化 — **完全支持双语输出** (`--lang he` 适用于
希伯来语 + RTL,可根据区域设置自动检测;现在动态发现详情也会被翻译,而不仅仅是限于
界面外壳 + 标题 + 静态字符串) — **CI 门控** (`--sarif`, `--fail-under`, `--exit-code`) —
**本地分数历史记录和离线百分位数** (`--trend`, `--percentile`, `--history`) — **附带敏感信息隐去功能的本地
日志记录** (`--verbose`, `--debug`, `--log`) — 通过渲染时的片段分割技术实现完整的希伯来语动态详情/修复
翻译 — 一套用于可靠性的误报/漏报 (FP/FN) 测试语料库 —
**引导模式**:在每次默认运行后打印“下一步建议”推荐模块
(同样存在于 `--json` 中的 `next_actions` 以及通过 `--next` 独立提供),外加重写过的
对话式 SKILL.md 指南,引导非技术用户了解每一个工具,而
无需记住任何命令参数 — **MCP 供应链审查** (`--vet-mcp`):在你信任它之前,检查每一个已连接的 MCP
server 是否存在未锁定版本的安装、明文传输、密钥透传以及宽泛的 OAuth scope
(判定为 SAFE / SUSPICIOUS / DANGEROUS,在本地只读运行;旨在解决 agent
供应链的头号缺口) — 一套**扩展的 Agentic 红队测试套件** (`--redteam`, `--dryrun`),涵盖了
工具投毒、MCP-response 注入、记忆投毒、多 agent 指令走私、
通过注入绕过审批,以及跨越 MCP-response、记忆和
子 agent 来源的脏输入到数据渗出链条 — 以及一个**风险引擎** (`--risk-paths`):组合攻击链检测,
用于揭示最高风险的能力路径 (RISK-01 至 RISK-11,包括在不受监控的主机上的高权限 agent 以及跨
agent 三角组合重组),且不会影响确定性的 A–F 评分。所有的检查都建立在真实的 OpenClaw schema 基础上 (数据源自
docs.openclaw.ai 以及实时的集群配置),因此它们能够在真实的安装环境中触发,而不会因为找不到
虚构的字段路径而默默失效。每一项发现还带有一个 **置信度** 评级 (HIGH = 确定性的
配置字段事实;MEDIUM = 值得人工审查的启发式匹配),并展示在报告、`--json`、
和 SARIF 中。该项目在 v0.16 版本中被重命名为 **ClawSecCheck**,而 v0.17 是一次基于外部
安全审查的稳定就绪检查:它修复了审批门控的误报问题 (检查现在会读取真实的
`tools.exec.mode` 而不是不存在的字段)、IPv6 gateway 绑定检测,跨**每一个**输出通道 (`--prompts`, `--json`,
`--sarif`, HTML) 的 prompt/报告清洗,并强化了发布管线。ClawSecCheck 依然只负责检查和指导 — 它
绝不会应用修复或更改你的配置。
## ⚖️ 局限性
- **启发式的本地审计,并非形式化的安全证明。** ClawSecCheck 仅分析
配置文本和已知模式;它无法推断所有可能的运行时
行为,也无法从形式上验证你 agent 的安全属性。
- **不能替代运行时红队测试。** 静态配置分析只是起点,
无法替代针对运行中 agent 的对抗性测试。
- **可能会产生误报和漏报。** 基于证据的限制机制虽然能降低噪音,
但启发式方法可能会漏掉新型的攻击模式,也可能误读边缘场景的配置。
- **读取范围有限:** 仅限配置文件、bootstrap markdown 文件,以及已安装 skill 的
文本 — 并不会对你的整个文件系统进行详尽扫描。
- **UNKNOWN 并不等于 PASS。** 无法读取的文件或无法解析的配置会被报告为
UNKNOWN,并在评分中剔除,绝不会被默默标记为安全。
## 🧪 测试
```
python3 -m pytest -q
```
## 📄 许可证
MIT — 请参阅 [LICENSE](LICENSE)。标签:Python, 基线评估, 子域名暴力破解, 无后门, 本地工具, 自动化检测, 逆向工具