flawopen.com/Teardowns/cve-2026-10032-a2ui-agent-button-xss
CVE-2026-10032:A2UI 智能体生成按钮中的 XSS
受影响版本的默认 Basic Catalog 中,openUrl 会把智能体提供的 URL 传给 window.open,且不限制 scheme。触发公告所述浏览器源影响需要用户点击渲染出的 Button;请升级到 0.10.2 或更高版本。[1]
想象一个服务终端:助手可以放置按钮,并把目的地写在自己提供的卡片上。终端只检查卡片里有没有地址,不检查它是否指向普通网页。访客仍须按下按钮;没有目的地规则时,浏览器可能把地址当成给终端的指令。修复会解析地址,并只接受 HTTP 或 HTTPS 目的地。[1], [2]
核心概念与专有名词
A2UI- 用于智能体生成界面的开源协议和项目;公告涉及 web_core 包的 Basic Catalog 操作。[1]
基础目录- A2UI 内置的一组函数,可供渲染界面操作使用;公告称其默认启用。[1]
框架映射
- 本指南所述弱点的 CWE 参考: CWE-79
根本原因剖析 (Root Cause)
受影响的 Basic Catalog 实现把 URL 参数当作可直接打开的字符串,而非需要 scheme 策略检查的不可信导航输入。API 只验证字符串类型;易受攻击的实现没有在调用 window.open(args.url, '_blank') 前限制 URL 协议。智能体控制的 Button.functionCall 可将值传到该 sink。用户仍须点击按钮;A2UI 公告称脚本可在受害应用的浏览器源中执行。上游修复解析 URL,只允许 http: 和 https:,并用 noopener,noreferrer 打开规范化 URL。此修复针对该导航 sink,不代表所有智能体生成界面都安全。[1], [2]
CVE-2026-10032:受影响版本与操作边界
| 部署条件 | 公告确认的事实 | 防御措施 |
|---|---|---|
| 默认 Basic Catalog 下的 @a2ui/web_core 0.9.0、0.9.1、0.9.2、0.10.0 或 0.10.1。 | A2UI 公告列出这些受影响版本,并说明 Basic Catalog 默认启用。 | 升级到 0.10.2 或更高版本,确认部署应用的解析版本。 |
| Button 函数调用来自智能体控制的 A2UI 数据,且有人点击。 | 公告描述点击后到达 openUrl 的路径及浏览器源影响;这不是零交互漏洞。 | 将操作参数视为不可信,并在打开 URL 的函数中验证。 |
| 应用使用 A2UI 的 React、Lit 或 Angular renderer。 | 公告将这些集成列入影响范围;易受攻击边界是 web_core 的共享 Basic Catalog 操作。 | 检查依赖解析并更新 web_core;不要认为 renderer 设置会移除该操作。 |
| 应用运行 @a2ui/web_core 0.10.2 或更高版本。 | 维护者将 0.10.2 列为修复版本:解析 URL、仅允许 HTTP/HTTPS,并使用 noopener,noreferrer。 | 保留有效和无效 scheme 的回归测试,并审查自定义 openUrl 替代实现。 |
攻击执行流程分解
源代码对比:漏洞与安全实现
易受攻击片段来自 A2UI 公告指出的实现。修复片段对应 PR #1707:解析并规范化地址,仅允许 HTTP/HTTPS,避免打开的页面控制来源页面或接收 referrer。项目类型和 imports 已省略;这些不是完整文件或概念验证代码。[1], [2]
源码摘录: basic_functions.ts — OpenUrlImplementation
export const OpenUrlImplementation = createFunctionImplementation(OpenUrlApi, args => {
if (args.url && typeof window !== 'undefined' && window.open) {
window.open(args.url, '_blank');
}
});
export const OpenUrlImplementation = createFunctionImplementation(OpenUrlApi, args => {
if (args.url && typeof window !== 'undefined' && window.open) {
const baseHref =
typeof window.location !== 'undefined' && window.location.href
? window.location.href
: undefined;
let url: URL;
try {
url = baseHref ? new URL(args.url, baseHref) : new URL(args.url);
} catch (e: any) {
throw new A2uiExpressionError(`Invalid URL specified: ${args.url}`, 'openUrl', e);
}
// 严格限制协议:仅允许 HTTP 和 HTTPS。
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
throw new A2uiExpressionError(`Unsupported URL scheme: ${url.protocol}`, 'openUrl');
}
// 始终使用 noopener 和 noreferrer,防止打开的页面控制来源窗口。
window.open(url.href, '_blank', 'noopener,noreferrer');
}
});
工程与系统安全加固清单
- ✓将所有直接和传递依赖的 @a2ui/web_core 升级到 0.10.2 或更高版本;检查 lockfile 和生产 bundle 的解析版本。[1]
- ✓盘点使用默认 Basic Catalog 及 React、Lit 或 Angular renderer 的应用;确认智能体数据能否定义 Button 函数调用。[1]
- ✓在导航 sink 验证 URL:先解析和规范化,再仅允许明确批准的 scheme(如 HTTP、HTTPS);不要依赖字符串前缀检查。[2]
- ✓使用
noopener,noreferrer打开外部目的地,并另行执行产品的用户确认或导航策略;两者针对不同风险。[2] - ✓测试普通 HTTP/HTTPS 和预期相对 URL 的解析,并确认畸形 URL 及所有非 HTTP(S) scheme 在调用
window.open前被拒绝。[2] - ✓将智能体编写的标签、目的地和函数参数视为不可信;检查每个操作在 sink 验证输入,不要假设 renderer 会清理。[1], [2]