关于 ZeroDOM
ZeroDOM 为应用安全团队和 AI Agent 提供确定性的浏览器与安全测试引擎。它比较真实会话以发现访问控制问题,并通过节省令牌的 MCP 接口支持浏览器任务。
主要功能
- 01双身份访问控制测试
- 02只读扫描整个应用
- 03端点重放与响应差异比较
- 04批量赋值与竞态检查
- 05稳定的浏览器元素句柄
- 06节省令牌的交互图
适用场景
- 01比较不同用户角色对端点的访问
- 02映射应用并测试其 GET 接口
- 03验证疑似批量赋值或 TOCTOU 问题
MCP 相关
ZeroDOM 是 MCP 服务,向 AI Agent 提供浏览器交互与安全测试工具,包括 repeat、probe 和 race 操作。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
24收录的工具列表 · 更新于 2 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| url | string | 是 | |
| frames | boolean | 否 | |
| verbose | boolean | 否 | |
| viewport_only | boolean | 否 | |
| check_occlusion | boolean | 否 |
详细介绍
ZeroDOM
让两个用户分别登录应用。它会找出访问控制漏洞。
ZeroDOM 使用两个身份驱动你的真实登录浏览器,分别重放相同的请求,并标记一个用户能访问、另一个用户却无法访问的内容所在之处—— IDOR / 访问控制漏洞,以确定性的方式发现。 核心功能开源,在本地运行,无需账号或 API 密钥,数据不会离开你的设备。
在漏洞搜寻功能之下,是一套面向 AI Agent 的确定性、低 token 感知引擎——同一核心驱动 scan、crawl 和任何浏览器操作任务。IDOR 只是它最擅长发现的问题。
网站 · 文档 · 体验场 · Discord · 快速入门 ↓
普通用户被拒绝访问管理控制台(401)——随后翻转一个由客户端控制的 Cookie 就能进入。ZeroDOM 会证明这一点:相同请求、两种身份、401 与 200。完整录屏(mp4)。
目录
- 为什么选择 ZeroDOM
- 快速入门
- 它如何搜寻漏洞——
compare和sweep - 在 AI Agent 中使用(MCP)
- 为什么 Agent 只会看到很少的 token
- 更多 CLI 功能
- 对比
- 安装
- 安全与范围
- 局限性
- 版本
- 贡献与开发
- 许可证
为什么选择 ZeroDOM
两个受众,一个引擎:
- 应用安全 —
compare/sweep: 确定性地使用两个身份进行 授权测试,可在 CI 或侦察流水线中以无头模式运行 — 无需 GUI,也无需账户。scan --js会添加 DOM-XSS sink、可调用 API 面,以及请求头安全态势;repeat/probe/race可将侦察转化为验证(Repeater、批量赋值差异,以及 TOCTOU 突发测试)。 - AI Agent — MCP: 扁平的交互图,与 Playwright 的
aria_snapshot相比,可减少 约 71% 的令牌;句柄可一对一解析,且不会因页面重新渲染而 失效。
访问控制失效是排名第一的 Web 漏洞(OWASP A01),也是自动化扫描器会漏掉的漏洞——因为要 发现它,就得知道谁应该有权做什么,而不只是对单个会话进行模糊测试。通常的做法是让人在 Burp 中手动操作:先以一个用户身份浏览应用,再换另一个用户浏览,然后凭肉眼比较差异。
ZeroDOM 会以机械化方式完成这件事。提供两个已登录会话;它会以各自身份重放同一请求,并报告 明确的确定性迹象:
access-boundary-split— 对同一请求,一个身份获得200,另一个获得401/403。如果 两者之间唯一的差异可由客户端控制(如 Cookie、请求头或参数),那就是访问控制失效。cross-identity-identical-response— 两个用户在针对个人资源的请求中获得字节完全一致 的响应正文:这就是跨租户 IDOR。
无需 LLM 猜测,也不会说“AI 觉得可能是这样”。ZeroDOM 会呈现明确迹象,并附上可证明问题的精确 重放结果——一份可供审查的差异报告,可直接放进漏洞报告。由你确认漏洞。
它通过 chrome.debugger 驱动你的真实 Chrome(中继模式),因此你的 Cookie、MFA 和 SSO
都已就绪;如果你不想触碰自己的会话,也可以使用一次性浏览器(--stealth)。无论哪种方式,
页面标记都不会离开你的设备,并且默认只读:破坏性操作和超出范围的主机都会被拒绝。
无论是作为一行命令行、侦察流水线阶段,还是通过 MCP 由AI Agent驱动的原生工具,它都能 出色地完成工作。相同的确定性原语,三种入口。
快速入门
10 秒即可看到运行效果 — 无需账户,也无需下载浏览器(直接运行 zerodom <url> 只会进行静态
获取,无需 Chromium):
pip install zerodom # or: uvx zerodom · npm i @vexralabs/zerodom
zerodom https://news.ycombinator.com # the interaction graph + a token report
这就是感知引擎:它提供一个扁平且可按 1:1 地址访问的图,而非 12k 个令牌的 HTML。
现在来看旗舰功能 — 查找 IDOR。 将两个已登录会话分别保存为 Playwright storage_state
文件(每个账户一个),然后比较两个会话对受保护端点的访问结果:
zerodom compare https://app.example.com/api/admin/dashboard \
--as user=user.json --as admin=admin.json
{
"identities": {
"user": { "status": 401, "bytes": 2616 },
"admin": { "status": 200, "bytes": 3469 }
},
"only_admin": ["Manage users", "Billing & plans", "Overview"],
"note": "admin authorized (200) where user denied (401) — broken access control if the
only difference is client-controllable"
}
整个流程就是这样:同一请求、两个身份,出现 401 与 200 的差异 → 得到一条待确认的线索。
only_admin 会列出普通用户不应看到的特权控件。
没有 storage-state 文件? 可以在 Playwright 中使用
context.storage_state(path="user.json") 捕获一个,或从已登录会话导出 Cookie。想扫描整个应用,
而非单个 URL? → zerodom sweep。
它如何搜寻 — compare 与 sweep
zerodom compare — 跨身份比较单个端点
使用每个已保存会话分别获取同一 URL,并比较响应。两个用户在私有资源上得到字节完全一致的内容,
意味着存在跨租户 IDOR;401 与 200 的差异则意味着访问边界失效。only_<name> 会列出每个身份可见、
而另一个身份不可见的可操作节点。
# Sweep a range of object ids through two identities:
seq 1 500 | sed 's#^#https://app.example.com/api/invoice/#' \
| zerodom compare - --as alice=alice.json --as bob=bob.json \
| jq 'select(.identical_body_pairs | length > 0)'
zerodom sweep — 一条命令扫描整个应用
compare 测试单个 URL。**sweep 会扫描整个应用:**先以一个身份爬取应用,绘制 GET 攻击面(页面 + JS 触发的 API 调用),然后在所有身份下重放每个范围内的 URL,并且只报告确定性的线索。
zerodom sweep https://app.example.com --as user=user.json --as admin=admin.json --format md
| severity | rule | url |
| -------- | ---------------------- | ------------------------------------- |
| medium | access-boundary-split | https://app.example.com/api/admin/... |
全程只读:仅重放 GET 请求,并丢弃破坏性 URL(--deny)。
--format md 会输出可直接用于报告的表格(默认为 JSONL)。这是“让它扫描一个有两个登录账号的应用,找出访问控制漏洞”的扫描流程。
两者都支持 --proxy(通过 Burp/Caido 路由流量)、--header(程序的 WAF 绕过令牌),以及可锁定的范围。检测到质询页面(Cloudflare / Turnstile / reCAPTCHA / hCaptcha)时,会通过范围限制下的逐级清除流程尝试处理;无法清除的拦截会如实报告为 blocked,绝不会在未经授权的目标上绕过拦截。
侦察发现线索后 — repeat / probe / race
应用映射会发现端点;这些命令则会对端点执行操作。repeat 是针对会话的 Repeater(--save 会将 HAR/.http 证据写入报告)。probe 会使用篡改后的请求体重放端点,并与基线进行差异比较——被接受且反射回来的字段可能是批量赋值漏洞的线索。race 会并发发送一批请求(使用同一个请求体,或通过重复的 --body 混合多种操作),以发现先检查后执行竞态(TOCTOU);标准库引擎始终可用,而 --engine http2 则会通过可选的 zerodom[race] 扩展,在一个连接上复用请求发送该批请求。
zerodom race https://app.example.com/api/coupon --body '{"code":"SAVE20"}' -n 30 \
--setup setup.json --check https://app.example.com/api/cart
这三个命令都通过 MCP 暴露给 Agent,名称为 zerodom_repeat / zerodom_probe / zerodom_race。
在 AI Agent 中使用(MCP)
标准 MCP 浏览器工具会向模型提供原始像素(速度慢,滚动后内容可能过时)或无障碍树(没有稳定句柄——重复控件会发生冲突)。zerodom-mcp 为 Agent 提供扁平、节省令牌的图谱,其中每个 click [45] 都会通过 CDP 确定性地指向唯一元素;而且,同一套工具还能执行其他工具无法完成的跨身份 IDOR 搜索。原因 ↓
ZeroDOM 是原生的 MCP 服务,因此 Claude、Cursor 或任何 MCP Agent 都可以使用相同的基本工具进行搜索。运行 zerodom setup 即可获得引导式首次运行流程(检查 Chromium、打印扩展程序路径和 chrome://extensions 操作步骤、生成下方配置、报告中继服务的可访问性——只打印并引导,无需账号,也不会有任何内容离开你的设备)。
// Claude Desktop: claude_desktop_config.json · Cursor: .cursor/mcp.json
{
"mcpServers": {
"zerodom": { "command": "uvx", "args": ["--from", "zerodom", "zerodom-mcp"] }
}
}
首次使用前运行一次(确保服务不会在工具调用期间下载):
uvx --from zerodom playwright install chromium。
使用 LangGraph、CrewAI、OpenAI Agents SDK、Pydantic AI、LlamaIndex、Google ADK 或 AutoGen?
examples/integrations/ 中提供了可直接运行的 MCP 示例——使用相同的服务,每个示例只需几行代码。
完整工具集(点击展开)
| 工具 | 功能 | |---|---| | `zerodom_parse_url(url, verbose=False, frames=False, viewport_only=False, check_occlusion=False)` | 导航并返回精简图;`frames=True` 还会读取同源和跨源 iframe(身份验证门户、付款字段) | | `zerodom_read_page(verbose=False)` | 重新读取实时 DOM,**不会导航** | | `zerodom_find(query)` | 仅返回与短语匹配的节点 | | `zerodom_click_node(node_id)` | 点击后返回**发生的变化**——导航后不久若同一页面上没有操作效果,会将其标记为可能未完成水合 | | `zerodom_fill_node(node_id, text)` | 通过真实按键输入——适用于 `contenteditable` 编辑器(Notion、Slack、Discord、Jira) | | `zerodom_hover(node_id)` | 悬停并显示由悬停触发的菜单/工具提示 | | `zerodom_press_key(node_id, key)` | 对聚焦节点按下按键(Enter、Escape、Tab,等等) | | `zerodom_upload_file(node_id, path)` | 将文件输入框的值设为本地路径 | | `zerodom_drag(source_node_id, target_node_id)` | 将一个节点拖到另一个节点上 | | `zerodom_scroll(direction, amount=800)` | 滚动并返回新显示的内容 | | `zerodom_new_tab(url=None)` | 打开一个标签页并将其设为活动标签页 | | `zerodom_list_tabs()` | 列出所有已打开的标签页,并标记活动标签页 | | `zerodom_switch_tab(tab_id)` | 将另一个已打开的标签页设为活动标签页 | | `zerodom_close_tab(tab_id=None)` | 关闭一个标签页(默认关闭活动标签页) | | `zerodom_screenshot(path=None)` | 对活动标签页截取整页屏幕截图并保存到磁盘 | | `zerodom_set_viewport(width, height)` | 调整视口大小以测试响应式设计 | | `zerodom_resize_window(width, height)` | 调整实际浏览器窗口大小(不只是页面视口) | | `zerodom_get_styles(node_id)` | 获取节点的精选计算样式和盒模型——用于设计/CSS 审查 | | `zerodom_network_log(clear=False)` | 查看活动标签页近期发出的请求/收到的响应 | | `zerodom_status()` | 诊断连接:中继/扩展程序是否可访问、活动标签页、近期中继日志 | | `zerodom_eval_js(code)` ⚠️ | 在真实页面中运行任意 JS 并返回结果 | | `zerodom_get_cookies()` ⚠️ | 列出活动标签页的 Cookie,**包括 `httpOnly` Cookie** | | `zerodom_get_storage()` | 列出活动页面持有的 `localStorage` / `sessionStorage` 键 | | `zerodom_hidden_fields()` | 列出页面的 `` 字段(CSRF 令牌、每视图载荷) | | `zerodom_crawl(url, max_pages=10, scope=None, deny=None)` | 广度优先遍历范围内的路由;每个页面生成一条 JSONL 记录(表单、链接、触发的 API 调用,以及从页面 JS 中读取的可调用接口 `js_endpoints`) | | `zerodom_scan(js=True)` | 检查活动页面的规则:DOM-XSS 接收器、其 JS 中的可调用 API 接口,以及 CSP/CORS 标头配置 | | `zerodom_repeat(url, method="GET", body=None)` | 通过活动会话发送一个请求(页面内 fetch)——一个返回 `{status, body}` 的 Repeater | | `zerodom_probe(url, tamper, body=None, method="POST")` | 使用篡改后的请求体重放并与基线进行差异比较——检测批量赋值/篡改 | | `zerodom_race(url, bodies=None, n=20, method="POST", setup=None, check=None)` | 通过活动会话(浏览器多路复用)并发突发请求,以标记检查后执行竞态(TOCTOU) | | `zerodom_set_scope(hosts, deny=None, max_rps=None)` | 将测试范围限制在已授权主机——通过代码强制执行,而非依赖信任 | | `zerodom_add_identity(name, storage_state=None, header=None)` | 注册第二个身份(例如用户 B)以进行跨租户测试 | | `zerodom_replay(url, method="GET", body=None, header=None, as_identity=None)` | 使用指定身份重放请求——供 Agent 使用的 Burp Repeater | | `zerodom_compare_identities(url, method="GET", body=None, identities=None)` | 使用每个身份请求同一 URL 并比较差异——标记相同响应以及 2xx 与 401/403 的响应差异 | | `zerodom_create_group(name, color="cyan")` | 创建一个有名称和颜色的标签页组,供 Agent 在其中隔离操作;浏览器重启后仍会保留 | | `zerodom_list_groups()` | 列出 Agent 的标签页组(没有标签页组 = 沙箱已关闭) | | `zerodom_use_group(name)` | 将某个组设为新标签页的目标组 | | `zerodom_close_group(name)` | 取消其标签页的分组并删除该组;关闭最后一个标签页会关闭沙箱 | | `zerodom_adopt_group(name)` | 将你自行整理的标签页组(按标题识别)交给 Agent | | `zerodom_restore_groups()` | 浏览器重启后,重新打开各组中记住的标签页 | ⚠️ `zerodom_eval_js` 和 `zerodom_get_cookies` 可以读取实时会话的 Cookie,并在已认证的浏览器中运行代码——这是开发者通过自己的 Agent 操作自己的浏览器时所需的能力;但如果不受信任的 MCP 客户端能够访问 `zerodom-mcp`,则会带来真实风险。这是有文档说明的边界,而非强制执行的边界。精简 Token 是设计使然:zerodom_find 用一行回答“派发按钮在哪?”,而不是返回整个图;操作返回差异(+/-/~),而非重新列出所有内容;viewport_only 会移除屏幕外的信息流节点;@card 分组可区分重复行。一旦 Agent 拥有一个标签页组,扩展程序就会拒绝连接到该组之外的任何标签页——而通过文件加载的作用域会被锁定,因此无人值守的 Agent 无法自行扩大范围。
在考虑是否推荐 ZeroDOM 作为 AI Agent 使用吗? 请阅读 SKILL.md——其中明确说明了 ZeroDOM 适用的情况(以及不适用的情况),并提供了可通过链接中的基准测试脚本重新验证的数据,而非营销宣传。
为什么 Agent 看到的 Token 如此之少
如今,操作浏览器的 Agent 有两种操作空间可选,但都不理想。像素(通过截图进行视觉识别)速度慢,而且页面一滚动,信息就会过时。无障碍树成本更低,但没有稳定的句柄——在 Hacker News 上,220 个可操作节点中有 102 个与另一个节点共享同一组 (role, name),因此无法指定要给哪篇故事点赞。
ZeroDOM 是第三种选择:一个扁平列表,每个条目都有一个能唯一对应某个元素的 ID;而用于让元素可点击的 CSS 选择器永远不会进入模型的上下文。
PAGE: Hacker News | https://news.ycombinator.com
[01] a 'Show HN: ZeroDOM — agents only need to know what they can click'
[02] a 'dev'
[03] a '214 comments'
Agent 看到的是 click [45];ZeroDOM 会将 [45] 解析为准确的 DOM 元素。解析过程是确定性的——输入 lxml,输出图,不使用 LLM,每次运行结果都相同。
经过测量,且可重新运行(脚本位于 benchmarks/):
对比 Playwright MCP 的 aria_snapshot(mode="ai") | 模型实际获取的快照 |
|---|---|
| Token 数 | 每个网站减少约 53–96% · 平均减少 71% |
| 每次操作的 Token 数 | 中位数约 10(ARIA:23–70,差异很大) |
| 在 111 个实时网站上(静态网页、SPA、Web 组件、iframe、仪表板……) | |
|---|---|
| 解析结果恰好对应一个元素的选择器 | 99.00% |
| 无效选择器 | 0 |
| 解析时间 | 中位数 55ms,p90 为 214ms |
| 相比原始 HTML 的节省 | 中位数 98.9% |
完整表格和方法说明:benchmarks/RESULTS.md。重点就在于处理难例——针对开放 Shadow Root 的 1,334 个选择器,每个都唯一对应一个元素。
更多 CLI 功能
zerodom https://example.com # the compact graph + a token report
zerodom https://example.com --find "sign in" # only the nodes that match
zerodom https://example.com --frames # also read inside iframes
zerodom https://example.com --json # full graph, selectors included
zerodom https://example.com --render # headless Chromium, for JS pages
zerodom https://example.com --stealth # throwaway Chrome over a CDP pipe, no port
cat targets.txt | zerodom inspect --pipe - # JSONL, one node per line
绘制攻击面地图 — zerodom crawl。 深度、经过身份验证的只读侦察:它会遍历已渲染的应用(可加载真实 JS SPA),严格遵守范围,并生成 JSONL 攻击面地图——每个页面的表单(及 CSRF 字段)、范围内的链接,以及其 JavaScript 发出的 API 调用。将其 api_calls 直接传给 compare,进行 IDOR 检查。
zerodom crawl https://app.example.com --storage-state session.json --max-pages 60
zerodom crawl https://app.example.com --relay # against your already-open Chrome
攻击面规则 — zerodom scan。 根据确定性的 YAML 规则集评估每个解析出的节点,并生成 JSONL 发现项——没有 CSRF 令牌的表单、缺少 CSRF 令牌的密码输入框、管理员/内部/调试链接,以及敏感输入项。规则是固定匹配键,而非表达式语言,因此规则文件中的内容不会被执行。
subfinder -d example.com | httpx -silent | zerodom scan - # into your recon pipeline
zerodom scan https://app.example.com --js # + DOM-XSS sinks, callable API surface, header posture
zerodom scan https://app.example.com --format md # Markdown table for a report
检查你已有的选择器 — zerodom audit。 读取 Playwright/
Cypress/Selenium 测试套件中的选择器,针对运行中的应用解析每个选择器,并报告 ok / dead /
ambiguous / invalid:zerodom audit tests/ --url http://localhost:3000。
经过身份验证的测试。 --proxy 通过 Burp/Caido/ZAP 路由(--insecure 信任
代理 CA);--header 'X-Bug-Bounty: …' 携带项目令牌;--storage-state 复用经过
人工验证的会话。适用于所有路径。仅测试你获准测试的目标。
查看图谱。 --screenshot page.png 会生成截图,并在每个节点上方标注编号;--html report.html 会生成一个自包含的检查器,左侧为图谱、右侧为页面(将鼠标悬停在线条上可突出显示对应元素)。两者都会输出 located 数量——能够解析到的选择器数量。
对比
坦诚地说:ZeroDOM 可与 Burp 配合使用(并非取而代之),也不是通用的浏览器自动化框架。它独特封装的是双身份授权测试方法——具有确定性、令牌消耗少,并且可以在流水线中以无头模式运行,也可以由 AI Agent 驱动。
如果你从事 AppSec,最值得关注的是最后一列。 如今,Burp + Autorize 是测试访问控制失效的标准方法,而且确实很好用——但它只能在 Burp 图形界面中运行。ZeroDOM 将同样的重放与比较方法带入可脚本化的 CLI 和 MCP Agent。
| ZeroDOM | Burp + Autorize | Playwright MCP | browser-use | |
|---|---|---|---|---|
| 跨身份授权检查 / IDOR,原生支持 | ✅ compare / sweep | ✅(启发式) | ❌ | ❌ |
| 可脚本化 · 无头 · CI 流水线 | ✅ CLI → JSONL | ❌ 受限于 Burp 图形界面 | ✅ | ~ 由大模型驱动 |
| 可用于差异比较、可附到工单的输出 | ✅ 可审查的差异 / MD 表格 | ⚠️ 图形界面判定(“是否已强制执行???”) | — | — |
可接入你的侦察工具链(subfinder→httpx→…) | ✅ 标准输入/标准输出 | ❌ | — | — |
| 可锁定范围,防止范围自行扩大 | ✅ 锁定范围 | ❌(由操作者驱动) | ❌ | ❌ |
| 具有确定性,解析时不使用大模型 | ✅ | ✅ | ✅ | ❌ |
| 驱动你实际登录的 Chrome | ✅ 中继 | ✅(代理) | 部分支持(CDP) | ✅ |
| 原生支持 Agent / MCP | ✅ | ❌ | ✅ | ✅ |
| 本地 · 无需账号 · 零外传 | ✅ | ✅ | ✅ | 取决于大模型 |
为什么选择 ZeroDOM 而不是用于自动化的 Autorize。 Autorize 是业界标杆——但它受限于 Burp 图形界面,采用启发式方法(其 README 本身就提示了误报和 “是否已强制执行???” 状态),而且没有无头/CLI/Agent 接口。因此它无法在 CI 中运行,无法接入你已有的侦察工具链,也无法由 AI Agent 驱动。ZeroDOM 将相同的重放与比较流程封装成一行命令,并输出 JSONL(或适用于工单的 Markdown 表格),强制执行锁定范围,并返回可审查的差异,而不是需要你仔细查看的判定结果。经验法则:如果你已经在 Burp 中点击操作,就使用 Autorize;如果授权检查必须自动化、可重复并原生适配流水线,就使用 ZeroDOM——例如每晚扫描 50 个应用、在 PR 上设置 CI 门禁,或让 Agent 不受值守地执行扫描。
安装
pip install zerodom # Python 3.10+ · or: uvx zerodom (runs straight off PyPI)
npm install @vexralabs/zerodom # TypeScript / Node 5.6+
仅当你使用由浏览器驱动的功能(from_page、--render、--screenshot、relay)时:
playwright install chromium(CLI 会在首次使用浏览器时自动执行此操作——只需下载一次,约 150 MB)。
**Relay 模式(使用你已登录的 Chrome)**需要安装随附的扩展:
zerodom setup # guided: Chromium, the extension, MCP config, relay
zerodom extension # prints the bundled extension's directory
# chrome://extensions → Developer mode → Load unpacked → select that directory
zerodom relay
每个版本还会附带 zerodom-extension-<version>.zip 及对应的 .sha256 文件。
快速上手库(Python / TypeScript):
from zerodom import ZeroDOM
graph = ZeroDOM.from_page(page) # any Playwright page, sync or async
print(graph.to_compact_text()) # what you send the model
selectors = graph.selector_map() # {"node_01": "#email", …} — stays your side
# Driving a browser agent? One call gives the full-page view + a ref map keyed to
# the [NN] refs the model reads, so `[03]` resolves straight to a selector:
text, refs = ZeroDOM.agent_snapshot(page) # viewport_only=False by default
page.click(refs["03"]) # act on what the model picked
import { ZeroDOM } from "@vexralabs/zerodom";
const graph = await ZeroDOM.fromPage(page);
console.log(graph.toCompactText());
// For a browser agent: full-page snapshot + ref map ([NN] -> selector).
const { text, refMap } = await ZeroDOM.agentSnapshot(page);
await page.click(refMap["03"]);
安全性与范围
这是一款安全工具,因此安全措施是强制执行的,而非仅作承诺:
- 默认只读——拒绝执行破坏性点击和填写操作。
- 范围可强制执行并锁定(
ZERODOM_SCOPE/zerodom_set_scope):主机允许列表、破坏性操作拒绝列表、速率限制。从文件加载的范围会被锁定,因此无人值守的 Agent 无法自行扩大权限范围。 - 拒绝无法驱动的目标——
chrome://、Web Store、开发者工具。 - 零出站流量——解析和 relay 都在本地运行;唯一的出站流量来自你指定的目标。没有遥测、没有账户、没有存储。(唯一例外是选择启用的 CAPTCHA 求解器,默认关闭,可通过
--no-solver禁用。) - Relay 模式下,操作期间标签页会被锁定——显示青色边框和可见光标,浏览器会阻止你自行输入,并显示“zerodom is driving this tab”横幅。
完整安全说明:SECURITY.md。
局限性
在基于它进行开发前,以下已知局限值得了解:
- **
compare的 IDOR 迹象需要两个真实的已登录身份。**它会显示迹象——不同身份收到相同响应,或一个身份收到 403、另一个收到 200——供你确认。它不会自主确认漏洞。 - **无法访问封闭的 Shadow DOM 根节点。**支持开放根节点;
{mode: 'closed'}对所有 API 都不可见,包括 Playwright。 - Canvas / WebGL 应用没有可供解析的内容——类似 Figma 的界面会将控件绘制为像素。
- 等待页面稳定有时间上限,不具备语义判断能力——
from_page/zerodom_read_page会等待 DOM 静止(≤1200 ms,参见 0.1.3),可以覆盖 hydration 和延迟注入节点,但无法判断任意应用条件(例如特定元素或网络响应)。遇到这类情况,请先等待你自己的条件,或传入settle=False,按当前状态读取。 zerodom <url>会执行静态抓取(不运行 JS)——对于由 JS 渲染的页面,请使用--render或 relay/MCP 路径。iframe 需要通过--frames启用。- 扩展仅支持未打包的开发者模式——
chrome.debugger和本地 WebSocket 不支持在 Web Store 上架(与 Playwright 自带的 CDP relay 类似)。 --stealth仅支持 POSIX 系统;MCP 服务一次只驱动一个浏览器会话(支持多标签页——这是有意设定的范围限制)。
版本
ZeroDOM 采用开放核心模式。本仓库中的所有内容——解析器、CLI、relay、stealth、scan/crawl/compare/audit、clearance ladder 和 MCP 服务——都属于免费的 Apache-2.0 Core,本身即可完整使用:单个操作人员即可在本地完成全部工作,无需账户或密钥。
| Core(Apache-2.0) | Enterprise(商业版) | |
|---|---|---|
| Parse · relay · stealth · scan · crawl · compare · audit · MCP | ✅ | ✅ |
| Clearance ladder(含可选启用的求解器)· 范围锁定 | ✅ | ✅ |
| 完全本地运行 · 零出站流量 · 无需账户 | ✅ | ✅ |
| 团队集群:多个目标/Agent、共享发现项存储、仪表板 | — | ✅ |
| 合规性导出包(SOC 2 / PCI / OWASP-ASVS 映射) | — | ✅ |
| 组织级范围策略 · SSO/RBAC · 审计日志 | — | ✅ |
| 并行/定时运行 · 精选规则包库 | — | ✅ |
| 优先支持 · SLA · 赔偿保障 | — | ✅ |
承诺:Core 将始终保持开源,并且完全在本地运行,不产生出站流量,也无需账户——这就是产品本身,并非试用版。Enterprise 是额外提供的团队层;它绝不会限制 Core、从 Core 向外发送数据,或为 Core 增加遥测功能。
Enterprise 功能、支持合同和赔偿保障:[email protected] (正在规划中——欢迎联系,共同塑造产品或成为设计合作伙伴)。
贡献与开发
uv sync && uv run playwright install chromium && uv run pytest
cd js && npm install && npm test # the TypeScript port's suite
最有帮助的贡献:提供一个选择器解析到错误元素的网页。
请提交 issue,并附上 URL 和 zerodom <url> --html report.html 的输出。贡献需遵守
Developer Certificate of Origin(Signed-off-by)。欢迎来
Discord 打个招呼。
许可证
Apache 2.0——请参阅 LICENSE。可在任何场景下使用,包括商业用途;也可将其嵌入 自己的产品中。ZeroDOM 是 Vexra Labs 的商标;该商标和 Enterprise 功能不受 Apache 授权条款涵盖。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。