
Prova de conceito demonstrando XSS armazenado no Table Widget do Appsmith, levando à escalada vertical de privilégios e à tomada total do administrador por meio de ataque XSS-para-CSRF.
Prova de Conceito para Escalação de Privilégios no Appsmith via XSS Armazenado
Divulgação: Originalmente relatado por mim via GHSA-5hw4-whxv-6794
⚠️ Uso apenas para testes de penetração/pesquisa autorizados.
| Campo | Valor |
|---|---|
| ID CVE | CVE-2026-30862 |
| Severidade | 🔴 Crítica |
| Pontuação CVSS | 9.1 |
| Vetor CVSS | [CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H] |
| CWE | CWE-79, CWE-269, CWE-352 |
| Produto Afetado | Appsmith ≤ 1.95 |
| Versão Corrigida | 1.96 |
| Aviso | GHSA-5hw4-whxv-6794 |
Uma vulnerabilidade Crítica de XSS Armazenado existe no Table Widget (TableWidgetV2). A causa raiz é a falta de sanitização de HTML no pipeline de renderização de componentes React, permitindo que atributos maliciosos sejam interpolados no DOM. Ao aproveitar o recurso "Invite Users", um atacante com uma conta de usuário comum ([email protected]) pode forçar um Administrador do Sistema a executar uma chamada de API de alto privilégio (/api/v1/admin/env), resultando em uma Assunção Total da Conta Administrativa.
1. Causa Raiz: Falta de Sanitização de Saída A vulnerabilidade reside no mecanismo de renderização do Table Widget
Arquivo: app/client/src/widgets/TableWidgetV2/component/cellComponents/BasicCell.tsx
O componente BasicCell falha em sanitizar os dados quando o columnType está definido como URL ou Plain Text. Ele retorna valores fornecidos pelo usuário sem tratamento, que são diretamente renderizados como filhos React, os quais o navegador interpreta como HTML executável.
Trecho de Código Vulnerável (Linhas 132-143 e 172-173):
const contentToRender = useMemo(() => {
switch (columnType) {
case ColumnTypes.URL:
// Interpolação direta de 'url' em href sem sanitização
return <a href={url} target="_blank">{value}</a>;
default:
return value; // Linha 141: Valor bruto retornado
}
}, [columnType, url, value]);
// Linha 173: Sink final onde o conteúdo não sanitizado é injetado no DOM
<Content ref={contentRef}>{contentToRender}</Content>
2. Vetor de Ataque: XSS-para-CSRF via Engenharia Social (Recurso de Convite) Embora o cookie SESSION seja protegido por HttpOnly, o XSRF-TOKEN é acessível via document.cookie. Como o Appsmith permite que qualquer usuário "convide" outros para seu aplicativo, um atacante pode usar isso como mecanismo de entrega para executar uma Falsificação de Requisição entre Privilégios (CPRF) dentro da sessão ativa do Administrador.
Passo 1: Verificação da Vulnerabilidade XSS
Faça login com uma conta de usuário comum: [email protected].
Crie um novo aplicativo e adicione um Table Widget.
Na propriedade Table Data, injete o seguinte:
[{ "id": 1, "payload": "" }]
-- Passo 2: Weaponização (Assunção Total do Administrador)
[email protected], atualize o Table Data com o seguinte payload projetado para modificar o ambiente administrativo:[
{
"id": 1,
"Status": "System Update Required",
"payload": "alert('Admin Privileges Granted to [email protected]'));\">"
}
]
Use o recurso "Share" para convidar o Administrador do Sistema ([email protected]) para o aplicativo. Isso força o Administrador a visualizar a tabela maliciosa ao abrir o convite.
Quando o Administrador abrir o aplicativo, o script é executado em segundo plano. Ele lê o XSRF-TOKEN do Administrador e envia uma requisição PUT para adicionar [email protected] à lista de permissões administrativas.
Resultado: Faça login novamente como [email protected]. Você agora terá acesso total às Configurações de Administrador e a todas as configurações da instância.
Tipo de Vulnerabilidade: XSS Armazenado / Escalação Vertical de Privilégios.
Severidade: 9.1 (Crítica) | CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H
Risco: Comprometimento completo da instância do Appsmith. Os atacantes obtêm acesso a variáveis de ambiente sensíveis, credenciais de banco de dados e a capacidade de modificar qualquer aplicativo dentro da instância.
Sanitizar Sinks: Envolva todas as saídas dinâmicas em BasicCell.tsx e componentes relacionados com DOMPurify.sanitize().
CSP Reforçado: Implemente uma política estrita de connect-src para impedir chamadas de API não autorizadas a endpoints administrativos a partir de payloads XSS.
https://github.com/user-attachments/assets/206a10e4-1619-4887-a552-99761baa0a29