cua-driver Wayland 合成器身份证明方案:超越 Sway 的精确浏览器窗口绑定架构

发布时间:2026/9/13 12:24:41
cua-driver Wayland 合成器身份证明方案:超越 Sway 的精确浏览器窗口绑定架构
cua-driver Wayland 合成器身份证明方案超越 Sway 的精确浏览器窗口绑定架构【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua导读本文剖析 Cua Driver 在 Linux Wayland 会话中实现精确浏览器窗口绑定exact browser attachment所需的核心机制——合成器身份证明compositor identity。Cua Driver 在绑定用户现有浏览器配置文件、按下某个精确的无障碍控件之前必须证明原生 toplevel、浏览器 PID、窗口几何、AT-SPI 应用/窗口、产品描述符与回环调试端点全部描述的是同一代浏览器进程本文将结合仓库中 Sway IPC 适配器、GNOME Shell WinRects 扩展与 KWin 候选适配器的源码实现逐一还原两条已验收路线Sway 与 GNOME、候选合成器评估、威胁模型以及发布验收矩阵。读完本文你将理解为什么标题、应用 ID 或屏幕坐标相似性不足以完成身份认证以及一套不依赖通用 unsafe 开关、在歧义时宁可拒绝也绝不误操作的合成器适配架构是如何设计与验证的。为什么 Wayland 下必须引入合成器身份证明Wayland 协议本身不向普通客户端暴露全局屏幕坐标也不提供跨合成器的窗口进程归属证明。现有配置文件existing-profile绑定流程需要打开浏览器内部页面并按下精确的无障碍控件在此操作发生之前Cua Driver 必须一次性证明以下六条身份线索全部指向同一代浏览器原生顶层窗口native toplevel浏览器进程 PID窗口几何geometryAT-SPI 应用/窗口节点产品描述符product descriptor回环loopback调试端点DevTools WebSocket。文档明确指出仅靠标题title、应用 IDapplication ID或屏幕坐标的相似性是不够的——攻击者或不相关的窗口完全可以复用这些值。当合成器无法证明精确身份时绑定流程必须在打开设置页或注入输入之前拒绝refuse而不能带着歧义继续执行。这一原则在源码中有直接映射平台层native_window与is_only_exact_native_window在 Wayland 分支下按「Hyprland IPC → Sway IPC → GNOME Shell 辅助扩展 → 通用 shell/AT-SPI 元数据」的顺序分派其中通用元数据路径只能获得geometry_exact: false的只读启发式绑定见 browser_platform.rs。已验收路线一Sway 合成器 IPC身份相关性容器 ID PID 几何 ↔ AT-SPI 树Sway 路线是仓库中最早验证通过的 Wayland 精确绑定路径。其原理是用合成器 IPC 将精确的容器container、PID 与矩形rectangle关联到 AT-SPI 树。实现位于 sway_ipc.rs通过swaymsg -r -t get_tree拉取合成器窗口树解析出每个节点的id、name、app_id、pid、rect、window_rect、deco_rect、focused、visible、fullscreen_mode等字段sway_ipc.rs对外暴露Window结构体id / pid / title / app_id / x / y / width / height / content_x / content_y / focused / visible / fullscreensway_ipc.rs提供按 ID、PID、标题、应用 ID 查找窗口的查询函数。其中window_for_pid的排序键是(focused, visible, 面积)即优先选择已聚焦、可见且面积最大的窗口用于处理一个进程开多个窗口的常规场景sway_ipc.rs。一个值得注意的工程细节Sway 通常在window_rect中报告客户端表面原点但部分服务端装饰server-decorated的 Wayland 客户端会把该原点留为 0只在deco_rect中暴露标题栏内缩。sway_ipc.rs据此做了两层退化推断先用deco_rect底部作为内容原点再退化为用rect.height - window_rect.height反推标题栏高度保证鼠标像素坐标与 AT-SPICoordType::Window相对坐标对齐sway_ipc.rs。这一推断逻辑在模块内有三组单元测试覆盖包括嵌套窗口 浮动窗口解析、装饰高度补全与隐式装饰补全sway_ipc.rs。焦点切换先认证、短暂聚焦、再恢复设置与同意阶段需要短暂聚焦该被认证的容器以完成浏览器自有内部导航然后恢复先前的容器。实现为with_focused_container先记录当前聚焦容器用[con_idN] focus精确聚焦目标轮询确认聚焦生效500ms 超时执行回调后再恢复并验证先前容器sway_ipc.rs。调用方在进入该函数前必须已经通过window_for_id验证了目标容器的 PID 与 ID——即先认证再动焦点。验收证据按计划文档记录Sway 路线已接受的浏览器为Google Chrome、Chromium、Microsoft Edge三个产品均完成了同一套完整矩阵录制了可播放视频且无意外结果。这也是该路线被标记为canonical Sway evidence的原因。已验收路线二GNOME Shell 的 WinRects 扩展v4 协议扩展提供的窄身份通道GNOME Mutter 是另一个非 wlroots 合成器家族普通 Wayland 客户端拿不到全局屏幕坐标org.gnome.Shell.Introspect.GetWindows被隐私策略拒绝也没有 layer-shell 可用于覆盖层。仓库因此维护了一个运行在 Shell 特权上下文中的 GNOME Shell 扩展cua WinRects源码位于 wayland-helper/winrectscua/extension.js。它对外暴露会话总线接口org.cua.WinRectsextension.js提供 Cua Driver 需要的窄身份通道GetVersion()—— 浏览器敏感 API 版本号当前返回 8extension.jsGetRects()—— 每个窗口的帧几何与表面缓冲原点。实现使用meta_window.get_stable_sequence()获取稳定窗口标识符配合get_pid()、get_frame_rect()、get_buffer_rect()、聚焦/最小化/可见/堆叠状态输出 JSON 数组extension.js。帧矩形与缓冲矩形分开保存正是为了应对 GTK 客户端阴影导致的两者偏移避免像素动作因阴影范围而落空Activate(id)—— 激活恰好一个Shell 稳定序列窗口并在约 100ms 后回读global.display.focus_window确认请求是否被接受extension.js。扩展元数据声明支持的 GNOME Shell 版本为 45–50协议版本 8metadata.json。完整能力含Capture截屏、MoveCursor/ClickPulse光标绘制、SetCursorState/SetCursorColor语义光标等可参见 wayland-helper/README.md。防替身验证不可变 D-Bus 唯一属主 系统安装的 gnome-shell扩展本身只是一半另一半是客户端侧的属主认证。GNOME 适配器在 shell_helper.rs 中实现其安全模型是文档所述 GNOME 路线的核心共四步解析不可变的唯一总线名通过GetNameOwner(org.cua.WinRects)拿到形如:1.xxx的唯一名称unique D-Bus owner并要求该名称以:开头shell_helper.rs验证属主进程通过GetConnectionUnixProcessID与GetConnectionUnixUser取得该唯一属主的 PID 与 UID要求 UID 等于当前用户验证属主是当前用户系统安装的gnome-shell读取/proc/{pid}/comm必须为gnome-shell且/proc/{pid}/exe指向的文件名必须是gnome-shell、属主为 root、权限位mode 0o022 0即系统安装、非用户可写见 shell_helper.rs浏览器敏感调用要求 API 版本 ≥ 4常量BROWSER_HELPER_API_VERSION 4语义光标则要求SEMANTIC_CURSOR_API_VERSION 8shell_helper.rs。为什么必须用唯一名称寻址如果直接向公开名org.cua.WinRects发请求会存在验证与激活之间的竞态——同会话中的无关进程可以在检查后替换公开名。而唯一名称由总线在连接建立时分配、不可被其他进程夺走因此验证后直接寻址该唯一属主即可关闭这一 TOCTOU 窗口。这也是文档中addresses that unique owner directly的源码实现。设置与同意期间扩展只对恰好一个目标窗口做短暂激活随后恢复并验证先前 Shell 聚焦窗口with_focused_window逻辑见 mod.rs。验收证据与拒绝策略计划文档记录GNOME 路线对Google Chrome已完成完整独立浏览器矩阵验收——单次源码提交上记录13 项已交付行为、3 项策略性拒绝、0 失败、0 跳过16 个可播放视频。Chromium 家族的其他产品仍需要各自在 GNOME 上积累产品专属证据因此不会因同一引擎家族而被自动豁免。适配器在以下情况下拒绝而非降级运行组件缺失、不兼容、被禁用或无法为一个浏览器进程区分多个窗口。文档特别强调启用一个通用的 unsafe-mode 开关不是可接受的生产依赖——宁可拒绝也不能以牺牲精确性换取可用性。仓库测试矩阵中也专门维护了 generic Wayland 现有配置拒绝 行断言在缺少被认证的 GNOME 辅助扩展时拒绝必须发生在任何 setup 副作用mutation之前见 standalone_browser_behavior_test.rs。候选合成器评估KDE Plasma / KWin可行但输入授权尚未就绪计划文档指出 KWin 6 脚本 API 可暴露每窗口内部 ID、PID、帧几何、堆叠顺序、活动状态与工作区激活能力。仓库中已存在对应的实验性实现 kwin_helper.rs它定义org.cua.KWinTarget只读 D-Bus 接口PROTOCOL_VERSION 1可返回KwinWindow记录token、pid、title、app_name、x/y/width/height、active、minimized、stacking并提供按pid token的精确匹配kwin_helper.rs但关键的available()函数当前恒为false因为 KWin 的 portal/libei 输入路径仍是焦点绑定的——libei 会把事件投递给 KWin 处理事件时恰好聚焦的表面先做焦点检查再发全局输入存在不可避免的 TOCTOU 竞态kwin_helper.rs。配套的 KWin 效果元数据同样声明仅提供只读可信身份元数据原始焦点绑定输入保持禁用kwin_target_helper.json。因此一个维护良好的 Cua KWin 组件可以返回带版本号、只读的身份记录并执行一次精确的 focus-and-restore 过渡适配器必须绑定「D-Bus 对端、KWin 代际、内部窗口 ID、PID、几何与 AT-SPI 窗口」通用的用户自定义脚本或标题查找都不够。在目标绑定输入能力落地之前KWin 路线保持发现可用、输入拒绝的状态。其他合成器ext-foreign-toplevel-list-v1只能贡献一部分证明标准ext-foreign-toplevel-list-v1协议暴露的是不透明的稳定 toplevel 标识符、标题与应用 ID但不提供 PID 与几何。仓库中的通用枚举实现 ext_toplevel.rs 正是如此记录仅含identifier / title / app_id三元组并为合成标识符保留0xF000_0000..0xFFFF_FFFE高端命名空间以避免与原生窗口 ID 冲突ext_toplevel.rs。文档的结论很明确该协议可以贡献证明中的一部分但不能独立授权变更操作mutation。wlroots 家族合成器可能额外暴露管理接口或合成器 IPC如 Sway 的 IPC、Hyprland 的 IPC但每条路线都必须独立证明全部必需字段后才能被接受不允许任何屏幕坐标回退screen-coordinate fallback。威胁模型每个适配器都必须覆盖的 8 类案例任何适配器与测试装置都必须覆盖以下场景任何歧义都必须产生稳定、非变更的结构化拒绝同标题双窗口两个同标题、几何相等或近似的浏览器窗口PID 复用 / 浏览器重启在批准与变更之间发生 PID 重用或浏览器重启诱饵应用应用 ID 或标题相同的非目标应用窗口动态变化设置期间窗口移动、切换工作区、最小化或关闭重映射后的陈旧对象 IDremap 之后合成器对象 ID 失效不完整或不匹配的 AT-SPI 树端点属主或代际漂移回环调试端点属主变化、连接代际错乱焦点恢复失败有界设置操作后未能恢复先前焦点。在源码层面这对应BrowserRefusalCode家族如BrowserWrongTargetRefused、BrowserBindingStale、BrowserBindingAmbiguous、BrowserEndpointOwnerMismatch以及browser_platform.rs中大量先比对再执行的守卫——例如 Hyprland 分支要求pid owner_pid address window_id且该 PID 恰好只有一个已映射窗口browser_platform.rsSway/GNOME 分支在返回NativeWindowInfo前逐一核对 PID 与窗口 ID 的归属browser_platform.rs。发布验收矩阵一个合成器受支持的最低门槛计划文档规定只有当**规范矩阵canonical matrix**记录以下全部 8 项证据后一个合成器才能被列为受支持精确来源合成器、发行版、浏览器产品与版本的精确溯源全量测试行setup、attach、reconnect、multi-tab多标签、stale-ref陈旧引用、background type后台类型、trusted input policy可信输入策略、ambiguous-window歧义窗口行全部覆盖外部状态预言机使用外部页面状态预言机验证结果而非依赖驱动自身的成功响应持续守卫连续的焦点、z-order/遮挡与无输入泄漏守卫光标保持在合成器暴露可信读回的前提下保持光标状态前后证据 视频变更前后的证据与精确源码提交点上的可播放视频显式环境结果对缺失 API 或无无障碍树的环境给出显式结果未知会话拒绝通用与未知的 Wayland 会话在变更前拒绝。这套矩阵解释了为何能用不等于受支持GNOME 路线的 Chrome 证据要求一次源码提交上 13 项行为 3 项策略拒绝 16 个可播放视频而 Sway 路线要求三个 Chromium 家族产品各跑完整矩阵。从 browser-existing-profile-attachment-plan.md 可以看到同一套验收哲学的延伸Safari、Firefox、无精确 setup 描述符的产品、无法识别的 UI 区域语言以及无精确合成器身份的 Wayland 会话一律返回结构化拒绝。总结Cua Driver 在 Wayland 上的精确浏览器绑定不是调用某个合成器 API 就能完成的功能而是一条由合成器身份证明 → 短暂聚焦 → 恢复验证 → 外部预言机验收构成的完整信任链。Sway 路线用 IPC 树中的容器 ID PID 几何完成认证GNOME 路线用运行在 Shell 特权上下文中的 WinRects 扩展配合「唯一 D-Bus 属主 → 系统 gnome-shell → API 版本门禁」完成认证KWin 与通用ext-foreign-toplevel-list-v1则分别处于只读身份已就绪、目标绑定输入缺失与仅能贡献部分证明的阶段。贯穿始终的设计约束是任何歧义都产生稳定拒绝任何通用 unsafe 开关都不被接受任何屏幕坐标回退都被禁止。对开发者而言这套架构与验收矩阵为在更多 Wayland 合成器上安全扩展计算机使用能力提供了可复制的范本。【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考