mcpField
Z
ZeroDOM

ZeroDOM

本地服务
zerodom.vexralabs.com安全33 天前更新

关于 ZeroDOM

ZeroDOM 为应用安全团队和 AI Agent 提供确定性的浏览器与安全测试引擎。它比较真实会话以发现访问控制问题,并通过节省令牌的 MCP 接口支持浏览器任务。

主要功能

  1. 01双身份访问控制测试
  2. 02只读扫描整个应用
  3. 03端点重放与响应差异比较
  4. 04批量赋值与竞态检查
  5. 05稳定的浏览器元素句柄
  6. 06节省令牌的交互图

适用场景

  1. 01比较不同用户角色对端点的访问
  2. 02映射应用并测试其 GET 接口
  3. 03验证疑似批量赋值或 TOCTOU 问题

MCP 相关

ZeroDOM 是 MCP 服务,向 AI Agent 提供浏览器交互与安全测试工具,包括 repeat、probe 和 race 操作。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"devhusnainai-zerodom": {
"command": "npx",
"args": [
"-y",
"@vexralabs/zerodom"
]
}
}
}
启动命令npx -y @vexralabs/zerodom

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypizerodom0.1.3
npm@vexralabs/zerodom0.1.3

工具

24

收录的工具列表 · 更新于 2 天前

参数类型必填说明
urlstring是
framesboolean否
verboseboolean否
viewport_onlyboolean否
check_occlusionboolean否

详细介绍

ZeroDOM 标志

ZeroDOM

让两个用户分别登录应用。它会找出访问控制漏洞。

ZeroDOM 使用两个身份驱动你的真实登录浏览器,分别重放相同的请求,并标记一个用户能访问、另一个用户却无法访问的内容所在之处—— IDOR / 访问控制漏洞,以确定性的方式发现。 核心功能开源,在本地运行,无需账号或 API 密钥,数据不会离开你的设备。

在漏洞搜寻功能之下,是一套面向 AI Agent 的确定性、低 token 感知引擎——同一核心驱动 scan、crawl 和任何浏览器操作任务。IDOR 只是它最擅长发现的问题。

PyPI npm License CI Claude MCP Discord

网站 · 文档 · 体验场 · Discord · 快速入门 ↓


普通用户被拒绝访问管理控制台(401),随后通过翻转一个由客户端控制的 Cookie 成功进入。ZeroDOM 以两种身份重放相同请求,并报告 401 与 200 的差异——访问控制漏洞。

普通用户被拒绝访问管理控制台(401)——随后翻转一个由客户端控制的 Cookie 就能进入。ZeroDOM 会证明这一点:相同请求、两种身份、401 与 200。完整录屏(mp4)。


目录


为什么选择 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。

ZeroDOMBurp + AutorizePlaywright MCPbrowser-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 授权条款涵盖。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。