FlawOpen

flawopen.com/Teardowns/cve-2026-10032-a2ui-agent-button-xss

● CVE-2026-10032 · CVSS 9.3[1] · Crítica
Pesquisa · FlawOpen

CVE-2026-10032: XSS em botões A2UI gerados por agentes

Nas versões afetadas de @a2ui/web_core, a ação openUrl do Basic Catalog padrão enviava uma URL fornecida pelo agente para window.open sem restringir o esquema. Uma pessoa precisava clicar no Button renderizado para produzir o impacto na origem do navegador descrito no aviso; atualize para 0.10.2 ou posterior.[1]

Vetor CVSSCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N[1]
💡 Explicação em Linguagem Simples (ELI5)

Imagine um quiosque em que um assistente pode colocar um botão, mas o destino está num cartão fornecido por ele. O quiosque verifica se há um endereço no cartão, mas não se ele leva a uma página web comum. Alguém ainda precisa apertar o botão; sem uma regra para o destino, porém, o navegador pode interpretar o endereço como instruções para o próprio quiosque. A correção analisa o endereço e aceita somente destinos HTTP ou HTTPS.[1], [2]

Conceitos Centrais e Termos

A2UI
Protocolo e projeto de código aberto para interfaces geradas por agentes; o aviso cobre a ação Basic Catalog do pacote web_core.[1]
Catálogo básico
Conjunto integrado de funções A2UI disponível às ações da interface renderizada. O aviso informa que vem habilitado por padrão.[1]
Ação de chamada de função
Ação declarativa de UI que identifica uma função e fornece argumentos; aqui, um Button renderizado podia chamar openUrl com uma URL do agente.[1], [2]
CWE-79
Classificação de neutralização inadequada de entrada durante a geração de páginas web; o aviso A2UI atribui essa classe ao problema de injeção no navegador.[1], [4]

Mapeamentos de frameworks

  • Referência CWE para a fraqueza descrita neste guia: CWE-79

Análise de Causa Raiz

A implementação afetada do Basic Catalog tratava o argumento URL como uma string a abrir, e não como entrada de navegação não confiável que exige uma política de esquemas. A API validava o tipo string, mas o código vulnerável não restringia o protocolo da URL analisada antes de chamar window.open(args.url, '_blank'). Um Button.functionCall controlado pelo agente podia levar o valor até esse ponto de saída. Uma pessoa ainda precisava clicar no botão renderizado; o aviso do A2UI descreve execução de script na origem do navegador da aplicação vítima. A correção upstream analisa o valor com o parser URL, permite somente http: e https: e abre a URL normalizada com noopener,noreferrer. Isso corrige esse ponto de navegação específico; não garante que toda UI gerada por agente seja segura.[1], [2]

CVE-2026-10032: versões afetadas e limite da ação

Condição de implantaçãoO que o aviso comprovaAção defensiva
@a2ui/web_core 0.9.0, 0.9.1, 0.9.2, 0.10.0 ou 0.10.1 com Basic Catalog padrão.O aviso lista essas versões como afetadas e diz que Basic Catalog vem habilitado por padrão.Atualize para 0.10.2 ou posterior e confirme a versão no aplicativo implantado.
Uma chamada de função de Button vem de dados A2UI controlados pelo agente e alguém clica nela.O aviso descreve o caminho até openUrl após o clique e o impacto na origem do navegador; não é zero-click.Trate os argumentos como não confiáveis e valide-os na função que abre a URL.
O aplicativo usa os renderizadores React, Lit ou Angular do A2UI.O aviso inclui essas integrações; a fronteira vulnerável é a ação compartilhada do Basic Catalog em web_core.Verifique a resolução do pacote e atualize web_core; não presuma que uma configuração do renderer remove a ação.
O aplicativo usa @a2ui/web_core 0.10.2 ou posterior.Os mantenedores indicam 0.10.2 como corrigido: análise de URL, permissão HTTP/HTTPS e noopener,noreferrer.Mantenha testes de regressão para esquemas válidos e inválidos e revise substituições próprias de openUrl.

Fluxo de Ataque Passo a Paso

Passo 1

Um agente fornece uma ação para Button

Dados de UI A2UI podem definir um Button com chamada de função e argumentos. Trate a ação como não confiável quando vier de um agente.[1]

Passo 2

O Basic Catalog resolve openUrl

O Basic Catalog padrão oferece openUrl; o esquema exige uma string, mas o código vulnerável não restringia o esquema da URL.[1]

Passo 3

Uma pessoa clica no Button renderizado

O caminho descrito no aviso requer um clique do usuário. Não o descreva como execução sem interação.[1], [2]

Passo 4

A ação chega a window.open

Antes do patch, openUrl passava a string fornecida a window.open sem analisar e permitir o protocolo. O aviso descreve execução de script na origem da aplicação vítima.[1]

Passo 5

A ação corrigida restringe a navegação

A correção resolve a URL, rejeita protocolos diferentes de HTTP e HTTPS e usa noopener,noreferrer no novo contexto. Atualize para @a2ui/web_core 0.10.2 ou posterior.[1], [2]

Código-Fonte: Vulnerável vs. Seguro

O trecho vulnerável vem da implementação identificada no aviso A2UI. O trecho corrigido representa a alteração upstream da PR #1707: analisar e resolver o endereço, permitir somente HTTP/HTTPS e impedir que a página aberta controle a página de origem ou receba o referenciador. Tipos e imports foram omitidos; não são arquivos completos nem uma prova de conceito.[1], [2]

Trecho de origem: basic_functions.ts — OpenUrlImplementation

IMPLEMENTAÇÃO VULNERÁVEL
export const OpenUrlImplementation = createFunctionImplementation(OpenUrlApi, args => {
  if (args.url && typeof window !== 'undefined' && window.open) {
    window.open(args.url, '_blank');
  }
});
PATCH SEGURO E ROBUSTO
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 estrita de protocolos: somente HTTP e HTTPS são permitidos.
    if (url.protocol !== 'https:' && url.protocol !== 'http:') {
      throw new A2uiExpressionError(`Unsupported URL scheme: ${url.protocol}`, 'openUrl');
    }

    // Use sempre noopener e noreferrer para impedir que a página aberta controle a janela de origem.
    window.open(url.href, '_blank', 'noopener,noreferrer');
  }
});

Lista de Verificação de Segurança para Engenharia

Fontes