flawopen.com/Teardowns/cve-2026-10032-a2ui-agent-button-xss
CVE-2026-10032: XSS en botones A2UI generados por agentes
En las versiones afectadas de @a2ui/web_core, openUrl del Basic Catalog predeterminado enviaba a window.open una URL del agente sin limitar su esquema. Una persona debía pulsar el Button renderizado para producir el impacto sobre el origen del navegador descrito en el aviso; actualiza a 0.10.2 o posterior.[1]
Imagina un quiosco donde un asistente coloca un botón y escribe el destino en una tarjeta que él mismo proporciona. El quiosco comprueba que haya una dirección, no que lleve a una página web normal. Alguien todavía debe pulsarlo; sin una regla para el destino, el navegador podría interpretar la dirección como instrucciones para el quiosco. La corrección analiza la dirección y solo acepta destinos HTTP o HTTPS.[1], [2]
Conceptos Clave y Términos
A2UI- Protocolo y proyecto de código abierto para interfaces generadas por agentes; el aviso cubre la acción Basic Catalog del paquete web_core.[1]
Catálogo básico- Conjunto integrado de funciones A2UI disponibles para acciones de la interfaz renderizada; el aviso dice que está habilitado por defecto.[1]
Mapeos de marcos
- Referencia CWE para la debilidad descrita en esta guía: CWE-79
Análisis de Causa Raíz
La implementación afectada de Basic Catalog trataba el argumento URL como una cadena para abrir, no como entrada de navegación no confiable que necesita una política de esquemas. La API validaba el tipo cadena, pero el código vulnerable no limitaba el protocolo de la URL analizada antes de llamar a window.open(args.url, '_blank'). Un Button.functionCall controlado por el agente podía llevar el valor al sink. Una persona debía pulsar el botón; el aviso de A2UI describe ejecución de JavaScript en el origen de la aplicación víctima. La corrección upstream analiza el valor con el parser URL, permite solo http: y https: y abre la URL normalizada con noopener,noreferrer. Corrige ese punto de navegación, no garantiza la seguridad de toda UI generada por agentes.[1], [2]
CVE-2026-10032: versiones afectadas y límite de la acción
| Condición de despliegue | Qué confirma el aviso | Acción defensiva |
|---|---|---|
| @a2ui/web_core 0.9.0, 0.9.1, 0.9.2, 0.10.0 o 0.10.1 con Basic Catalog predeterminado. | El aviso enumera estas versiones como afectadas y señala que Basic Catalog viene habilitado por defecto. | Actualiza a 0.10.2 o posterior y verifica la versión en la aplicación desplegada. |
| Una llamada de función Button procede de datos A2UI controlados por agente y alguien hace clic. | El aviso describe la ruta hasta openUrl tras el clic y el impacto en el origen del navegador; no es zero-click. | Trata los argumentos como no confiables y valídalos en la función que abre la URL. |
| La aplicación usa los renderizadores React, Lit o Angular de A2UI. | El aviso incluye estas integraciones; el límite vulnerable es la acción compartida de Basic Catalog en web_core. | Comprueba el paquete y actualiza web_core; no supongas que una configuración del renderer elimina la acción. |
| La aplicación ejecuta @a2ui/web_core 0.10.2 o posterior. | Los mantenedores señalan 0.10.2 como corregido: análisis URL, permiso HTTP/HTTPS y noopener,noreferrer. | Mantén pruebas de regresión para esquemas válidos e inválidos y revisa reemplazos propios de openUrl. |
Flujo de Ataque Paso a Paso
El agente proporciona una acción para Button
Los datos de UI de A2UI pueden definir un Button con llamada a función y argumentos. Trata como no confiable la acción que proceda de un agente.[1]
Basic Catalog resuelve openUrl
El Basic Catalog predeterminado ofrece openUrl; el esquema exige una cadena, pero el código vulnerable no limitaba el esquema URL.[1]
La acción llega a window.open
Antes del parche, openUrl pasaba la cadena a window.open sin analizar ni permitir primero el protocolo. El aviso describe ejecución en el origen de la aplicación víctima.[1]
Código Fuente: Vulnerable vs. Seguro
El fragmento vulnerable procede de la implementación señalada en el aviso A2UI. El corregido representa el cambio upstream de la PR #1707: analizar y resolver la dirección, permitir solo HTTP/HTTPS e impedir que la página abierta controle la página de origen o reciba el referente. Se omiten tipos e imports; no son archivos completos ni una prueba de concepto.[1], [2]
Fragmento de origen: 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);
}
// Lista estricta de protocolos: solo se permiten HTTP y HTTPS.
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
throw new A2uiExpressionError(`Unsupported URL scheme: ${url.protocol}`, 'openUrl');
}
// Usa siempre noopener y noreferrer para evitar que la página abierta controle la ventana de origen.
window.open(url.href, '_blank', 'noopener,noreferrer');
}
});
Lista de Verificación de Seguridad para Ingeniería
- ✓Actualiza todas las dependencias directas y transitivas de @a2ui/web_core a 0.10.2 o posterior; confirma la versión del lockfile y del bundle de producción.[1]
- ✓Inventaría aplicaciones con Basic Catalog y renderizadores React, Lit o Angular; comprueba si los datos del agente pueden definir llamadas de función Button.[1]
- ✓Valida la URL en el punto de navegación: analízala y resuélvela primero, y después permite solo esquemas aprobados expresamente como HTTP y HTTPS; no uses prefijos de cadena.[2]
- ✓Abre destinos externos con
noopener,noreferrery aplica por separado la política de consentimiento o navegación del producto; son controles para riesgos distintos.[2] - ✓Prueba que las URL HTTP/HTTPS y relativas previstas se resuelvan, y que URL malformadas y esquemas no HTTP(S) se rechacen antes de
window.open.[2] - ✓Trata etiquetas, destinos y argumentos de función del agente como datos no confiables; valida cada acción en su punto de salida sin suponer que el renderer los sanea.[1], [2]