
Blog sobre CVE-2026-59827, desserialização insegura da saída de consulta H2
GHSA-w95f-x9v9-wv36 | CVSS 9.9 Crítico | CWE-502: Desserialização de Dados Não Confiáveis
O CVE-2026-59827 é uma vulnerabilidade crítica de execução remota de código no Metabase, a popular plataforma de business intelligence e análise de dados de código aberto. A falha decorre de como o Metabase lida com os resultados de consulta retornados por uma conexão de banco de dados H2. Quando uma consulta SQL nativa contra uma fonte H2 retorna uma coluna tipada como OTHER, o Metabase desserializa os bytes brutos dessa coluna em um objeto Java sem realizar qualquer validação. Um usuário autenticado que pode executar consultas nativas é, portanto, capaz de introduzir um payload serializado malicioso no conjunto de resultados e acionar a execução arbitrária de código no servidor que hospeda o Metabase.
A vulnerabilidade recebeu uma pontuação CVSS de 9.9, refletindo as pré-condições mínimas necessárias e a execução completa de código no servidor que resulta da exploração bem-sucedida.
O Metabase distribui duas edições paralelas do mesmo ciclo de lançamento. A edição de código aberto usa números de versão prefixados com 0 — por exemplo, v0.61.1. A edição empresarial (comercial) usa números de versão prefixados com 1 — por exemplo, v1.61.1. Ambas as edições compartilham a mesma base de código subjacente e são lançadas juntas, portanto, uma vulnerabilidade que afeta v1.61.0 afeta igualmente v0.61.0. Ao longo deste artigo, os números de versão são escritos usando o prefixo empresarial 1.xx, mas cada versão afetada corresponde diretamente à sua contraparte de código aberto 0.xx substituindo o 1 inicial por 0.
Tanto o CVE-2026-59826 quanto o CVE-2026-59827 foram divulgados juntos em julho de 2026. Eles compartilham faixas de versão sobrepostas, mas possuem pontos de correção diferentes.
As versões empresariais vulneráveis são 1.58.0 a 1.58.14, 1.59.0 a 1.59.11, 1.60.0 a 1.60.6.2 e 1.61.0 a 1.61.1.3. As versões de código aberto correspondentes são 0.58.0 a 0.58.14, 0.59.0 a 0.59.11, 0.60.0 a 0.60.6.2 e 0.61.0 a 0.61.1.3.
Uma correção interna foi emitida inicialmente como 1.61.1.4 (empresarial) e 0.61.1.4 (código aberto). A primeira versão corrigida publicamente disponível na linha 1.61 é a 1.61.2 (v1.61.2.x / v0.61.2.x). As instâncias do Metabase Cloud foram corrigidas automaticamente pelo provedor.
As versões empresariais vulneráveis são 1.55.0 a 1.58.15.0, 1.59.0 a 1.59.11, 1.60.0 a 1.60.6.2 e 1.61.0 a toda a linha 1.61.1.x. A primeira versão pública totalmente corrigida é a 1.61.2 (v1.61.2.x / v0.61.2.x). O escopo do CVE-2026-59826 é mais amplo, alcançando a linha de versão 1.55, refletindo a presença mais antiga do caminho de código de criação de banco de dados insuficientemente validado que ele explora.
O mecanismo de serialização do Java permite que um objeto na memória seja convertido em um fluxo plano de bytes, armazenado ou transmitido, e depois reconstruído chamando ObjectInputStream.readObject(). A propriedade crítica desse mecanismo é que a reconstrução executa código. Construtores de classe, sobrescritas de readObject e finalizadores são executados durante a desserialização. Se os bytes sendo lidos vêm de uma fonte não confiável, um atacante pode manipulá-los para acionar chamadas de método arbitrárias através de uma sequência de classes existentes e legítimas já carregadas na JVM. Essas sequências são conhecidas como cadeias de gadgets (gadget chains).
As cadeias de gadgets não exigem a introdução de nenhum novo código na aplicação. Elas exploram a fiação de classes de bibliotecas existentes cujos métodos normais, quando chamados na ordem correta durante a desserialização, eventualmente alcançam um destino como Runtime.exec(). Ferramentas como ysoserial existem especificamente para gerar esses payloads para bibliotecas amplamente implantadas, como Apache Commons Collections, Spring Framework e outras.
O H2 é um banco de dados relacional embutido puro Java. Ele define um tipo de coluna SQL especial chamado OTHER que atua como um bypass para objetos Java arbitrários. Quando o H2 armazena um valor em uma coluna OTHER, ele escreve os bytes produzidos por ObjectOutputStream do Java. Quando lê o valor de volta, ele chama ObjectInputStream.readObject() para reconstruir o objeto. Os bytes serializados brutos também podem ser fornecidos diretamente em uma consulta usando a sintaxe literal hexadecimal do H2:
SELECT CAST(X'ACED0005...' AS OTHER);
-- or
SELECT X'ACED0005...'::OTHER;
O prefixo ACED seguido de 0005 é o número mágico e a versão do protocolo do fluxo de serialização Java. Qualquer string hexadecimal começando com ACED0005 é um fluxo de objeto serializado Java.
Quando o H2 processa essa consulta, ele desserializa os bytes hexadecimais do lado do banco de dados. O objeto resultante é então passado de volta para a aplicação chamadora através do ResultSet JDBC. Se a aplicação inspeciona o valor da coluna — por exemplo, para formatá-lo para exibição — ela pode acionar processamento adicional. Isso é exatamente o que o Metabase faz no caminho de código vulnerável.
O Metabase recebe o ResultSet JDBC do driver H2 e inspeciona os metadados da coluna para decidir como renderizar cada valor para o usuário. Quando encontra uma coluna com o tipo JDBC Types.OTHER (também relatado como JAVA_OBJECT), as versões vulneráveis do Metabase tentam desserializar os bytes brutos para produzir uma representação exibível. Esta chamada de desserialização, ObjectInputStream.readObject(), executa sem qualquer filtragem de lista branca ou validação de classe.
A sequência de eventos é:
OTHER contendo um payload serializado elaborado.JAVA_OBJECT no ResultSet.OTHER e chama readObject() nos bytes.Runtime.exec() e executando o comando do atacante como o usuário do sistema operacional que executa o processo do Metabase.As versões corrigidas resolvem o problema inspecionando os metadados do resultado JDBC antes de tentar qualquer desserialização. Se uma coluna for tipada como JAVA_OBJECT, o Metabase agora a rejeita imediatamente, em vez de tentar analisá-la.
A exploração requer autenticação. O atacante deve possuir uma conta no Metabase com permissão de execução de consultas nativas em um banco de dados com backend H2. Contas de administrador satisfazem isso por padrão. Contas de usuário regular também podem satisfazer esse requisito se um administrador lhes concedeu a permissão de dados de consultas nativas para o banco de dados relevante.