
Análise do CVE-2026-5281 (Chrome Dawn WebGPU UAF), ferramentas de validação em laboratório e ambiente reproduzível para builds vulneráveis vs corrigidas.
Esta vulnerabilidade afetou um dos clientes para os quais prestamos serviços. Este repositório é a nossa contribuição para a pesquisa original: um ponto de partida centralizado para o grupo, de modo que, se uma vulnerabilidade semelhante que afete este componente aparecer novamente, já teremos a base preparada. Ele reúne a teoria por trás do bug, um resumo documentado das descobertas do pesquisador original e um conjunto de ferramentas práticas para verificar a exposição em um ambiente de laboratório.
Nota: Eu gostaria de ter compartilhado mais desta pesquisa, mas devido a restrições da empresa não posso divulgá-la mais. Tudo o que está incluído aqui foi revisado e não viola nenhum acordo ao qual estou sujeito. O repositório está, portanto, arquivado no seu estado atual.
Em 1º de abril de 2026, o Google lançou uma atualização de segurança do Chrome que corrigia 21 vulnerabilidades, uma das quais, CVE-2026-5281, já estava sendo ativamente explorada no mundo real no momento da divulgação. Três dias depois, a CISA a adicionou ao catálogo de Vulnerabilidades Conhecidas e Exploradas e emitiu uma diretiva operacional vinculante exigindo que as agências federais aplicassem o patch. Nesse ponto, ela já havia nos afetado.
Este repositório existe por um motivo: para que, na próxima vez que algo assim acontecer, tenhamos um ponto de partida em vez de começar do zero. Ele reúne:
Quando você quer entender por que uma vulnerabilidade existe, você começa pelo que o sistema foi construído para fazer e por quais premissas ele foi projetado.
O WebGPU expõe uma API para realizar operações, como renderização e computação, em uma Unidade de Processamento Gráfico. O WebGPU não é uma tentativa de expor OpenGL ou OpenGL ES (Embedded Systems). É uma nova API construída sobre as ideias de APIs modernas, como Direct3D 12, Metal e Vulkan.
O WebGPU é o substituto moderno do WebGL, a antiga API de GPU que os navegadores usam há anos. A principal diferença é que o WebGPU foi projetado do zero com foco em segurança e gerenciamento explícito de recursos. Você declara o ciclo de vida de cada buffer, textura e pipeline. O navegador atua como uma camada de validação entre seu JavaScript e o hardware da GPU.
Os objetos no centro desta vulnerabilidade, em ordem de criação:``` GPUAdapter ← represents a physical GPU or software fallback └─ GPUDevice ← your logical connection to the adapter; owns everything ├─ GPUBuffer ← a chunk of GPU-accessible memory ├─ GPUShaderModule ← a compiled WGSL shader program ├─ GPUComputePipeline ← a shader wired to a pipeline layout ├─ GPUBindGroup ← binds buffers as inputs to a pipeline ├─ GPUCommandEncoder ← records a sequence of GPU commands └─ GPUQueue ← submits recorded commands to hardware
A regra que importa aqui: todo objeto pertence ao GPUDevice. Destruir um buffer enquanto o dispositivo ainda tem comandos em andamento que o referenciam é explicitamente ilegal segundo a especificação. A implementação Dawn deveria detectar e rejeitar isso. CVE-2026-5281 é um caso em que ela não o fez.
---
---
---
<div id='whatisdawn'/>
## ***⚙️ O que é Dawn?***
- **[Dawn - Implementação WebGPU de Código Aberto](https://dawn.googlesource.com/dawn)**
> Dawn é uma implementação de código aberto e multiplataforma do padrão WebGPU em desenvolvimento. Ela expõe uma API nativa em C++ que espelha a IDL do WebGPU com algumas extensões.
Dawn é a biblioteca C++ dentro do Chrome que traduz chamadas JavaScript do WebGPU em comandos GPU nativos da plataforma. No Windows, ela tem como alvo o D3D12; no macOS, o Metal; e no Linux, o Vulkan. Ela fica entre o mecanismo JavaScript do Chrome e o driver de hardware, sendo responsável por quatro coisas: validar chamadas de API, serializar comandos, rastrear o tempo de vida dos objetos e expor erros de volta ao JavaScript.
CVE-2026-5281 reside na parte de rastreamento de tempo de vida. Especificamente, por quanto tempo a Dawn mantém os objetos de buffer de GPU vivos enquanto comandos que os referenciam ainda estão pendentes de execução na fila de hardware.```
JavaScript (V8)
│ WebGPU API calls
▼
Dawn (C++) - validates, serializes, tracks lifetimes, reports errors
│
▼
D3D12 (Windows) - Metal (macOS) - Vulkan (Linux)
│
▼
GPU hardware driver
│
▼
Physical GPU - shader cores, VRAM
Você precisa de um modelo mental claro de onde as coisas vivem na memória antes que um Use-After-Free faça sentido intuitivo.``` High addresses ┌────────────────────────────────────┐ │ Kernel space │ The OS and drivers live here. │ │ User-mode code cannot touch it. ├────────────────────────────────────┤ │ Stack │ Function call frames. Fast. │ (grows downward) │ Freed automatically when the │ │ function returns. ├────────────────────────────────────┤ │ Heap │ Dynamic allocations - malloc, new, │ (grows upward) │ smart pointers like Ref. │ │ Freed only when you say so. ├────────────────────────────────────┤ │ BSS / Data / Text │ Globals, constants, compiled code. └────────────────────────────────────┘ Low addresses
Os objetos C++ do Dawn, como o objeto interno que dá suporte a um GPUBuffer, vivem no heap. Eles são contados por referência: um ponteiro inteligente mantém uma contagem de quantas coisas possuem uma referência ao objeto. Quando essa contagem chega a zero, o destrutor é executado e a memória é devolvida ao alocador.
Um GPUBuffer tem duas representações ao mesmo tempo, uma no lado da CPU e uma na GPU:```
CPU side (Dawn, system RAM)
└─ C++ object - metadata, state flags, and a hardware handle
│
│ handle: ID3D12Resource* (D3D12) - MTLBuffer (Metal) - VkBuffer (Vulkan)
▼
GPU side (driver, VRAM)
└─ Actual memory allocation on the graphics card
Quando o JavaScript chama buffer.destroy(), o comportamento pretendido é: marcar o objeto como destruído, decrementar a contagem de referências, liberar o handle de hardware e liberar a VRAM. O bug em CVE-2026-5281 faz com que a VRAM seja liberada enquanto a fila de comandos da GPU ainda mantém uma referência a esse handle de hardware, o que significa que a GPU está lendo ou escrevendo ativamente em memória que não pertence mais a ela.
CWE-416: Use After Free (MITRE)
Referenciar memória após ela ter sido liberada pode fazer com que um programa trave, use valores inesperados ou execute código. O uso de memória previamente liberada pode ter inúmeras consequências adversas, desde a corrupção de dados válidos até a execução de código arbitrário.
Um Use-After-Free segue um padrão fixo de três etapas e é uma das classes de bugs de segurança de memória mais consistentemente exploradas em segurança de navegadores:```
Após o passo 2, o alocador pode entregar essa mesma região de memória para uma alocação completamente diferente. Se um atacante puder controlar o que é colocado nessa região liberada, uma técnica chamada heap grooming, ele pode controlar o que o ponteiro obsoleto lê de volta. É assim que um bug de segurança de memória se torna execução de código.
UAF no lado da GPU é mais difícil de observar do que UAF no lado da CPU, porque:
- O "alocador" é o alocador de VRAM do driver da GPU, não o malloc do sistema.
- O "ponteiro obsoleto" é um handle de hardware ainda referenciado pela fila de comandos.
- A GPU executa comandos de forma assíncrona; a CPU já avançou muito antes de a falha ocorrer.
---
---
---
<div id='thevulnerability'/>
## ***🕳️ A Vulnerabilidade***
---
<div id='thevulnerability-whatweknow'/>
### ***📋 O Que Sabemos de Fontes Públicas***
O que se segue é fundamentado inteiramente no que foi confirmado publicamente.
- **[NVD: CVE-2026-5281](https://nvd.nist.gov/vuln/detail/CVE-2026-5281)**
> Um use-after-free em Dawn no Google Chrome anterior à versão 146.0.7680.178 permitiu que um atacante remoto que tivesse comprometido o processo de renderização executasse código arbitrário por meio de uma página HTML especialmente criada.
- **[The Hacker News: 1º de abril de 2026](https://thehackernews.com/2026/04/new-chrome-zero-day-cve-2026-5281-under.html)**
> O Google está ciente de que existe um exploit para CVE-2026-5281 em circulação.
- **[Help Net Security: 1º de abril de 2026](https://www.helpnetsecurity.com/2026/04/01/google-chrome-zero-day-cve-2026-5281/)**
> A CVE-2026-5281 foi sinalizada por um caçador de bugs pseudônimo (86ac1f1587b71893ed2ad792cd7dde32), que anteriormente relatou duas vulnerabilidades que foram corrigidas na atualização do Chrome lançada em 23 de março de 2026: um estouro de buffer no heap em WebGL (CVE-2026-4675) e outro bug de use-after-free em Dawn (CVE-2026-4676). O caçador de bugs também relatou um terceiro use-after-free em Dawn (CVE-2026-5284) que foi corrigido desta vez.
---
<div id='thevulnerability-executionlayers'/>
### ***🔗 Do JavaScript ao Hardware***
Para entender onde um UAF em Dawn pode se originar, é útil ver exatamente como uma chamada WebGPU percorre o caminho de uma linha de JavaScript até o hardware físico:```
JavaScript
↓ navigator.gpu → adapter → device → buffer / pipeline / encoder
↓ queue.submit([commandBuffer]) ← validation happens here
↓ buffer.destroy() ← if this races GPU execution, UAF
Dawn (C++) - validates API calls, serializes commands, tracks lifetimes
↓ translates WebGPU calls to platform-native API calls
D3D12 (Windows)
↓ ID3D12CommandQueue::ExecuteCommandLists()
↓ hardware handle for the buffer passed to the driver
GPU hardware
↓ shader cores execute the queued commands
↓ if the buffer was freed prematurely → they access freed VRAM ← UAF
A tensão fundamental é que queue.submit() e buffer.destroy() são ambas chamadas de API JavaScript que retornam imediatamente, mas a GPU executa os comandos submetidos de forma assíncrona, potencialmente muito depois de ambas as chamadas terem retornado. Dawn precisa manter os objetos de buffer vivos durante toda a duração da execução da GPU, não apenas até a chamada JavaScript retornar.
Quando o UAF dispara, a GPU atinge o que o D3D12 chama de evento "Device Removed". A sequência é:```
Isto é também o que o runner de testes automatizados neste repositório detecta: ele observa exatamente esses sinais de console para determinar se a vulnerabilidade pode ser acionada numa determinada versão do Chrome.
---
<div id='thevulnerability-impact'/>
### ***💥 Impacto e Requisitos de Exploração***
A descrição da NVD é específica sobre uma restrição importante: a exploração exige que o atacante já tenha comprometido o processo de renderização. Isto significa que o CVE-2026-5281 não é um RCE autônomo de um clique a partir do zero, é uma fuga da sandbox que se torna parte de uma cadeia.
Na prática, uma cadeia de ataque completa seria algo como:```
Initial access ← some other vulnerability gets code running in the renderer
↓
CVE-2026-5281 ← UAF in Dawn used to escape the renderer sandbox
↓
Arbitrary code ← execution in a higher-privilege Chrome process or OS context
Este é exatamente o modelo de exploração que torna as vulnerabilidades de GPU do navegador de alto valor: uma vez dentro do renderizador, a Dawn é um dos próximos alvos naturais, pois lida com memória em nível de hardware com o tipo de complexidade assíncrona que produz essas janelas de temporização.
O impacto confirmado na época da divulgação foi a execução arbitrária de código, e o banco de dados Vulners registra corrupção de dados e travamentos do navegador como efeitos adicionais observados.
A CVE-2026-5281 não apareceu isoladamente. Foi o quarto zero-day do Chrome em 2026, um ano que já estava no ritmo para superar o total de oito zero-days de 2025 antes do final do primeiro trimestre.
| Data | Evento |
|---|
| Fevereiro de 2026 | CVE-2026-2441 corrigida, UAF no componente CSS do Chrome, explorada ativamente |
| 10 de março de 2026 | CVE-2026-3909 e CVE-2026-3910 corrigidas, ambas zero-days exploradas ativamente |
| 23 de março de 2026 | CVE-2026-4675 (estouro de buffer no heap do WebGL) e CVE-2026-4676 (UAF na Dawn) corrigidas, mesmo relator da CVE-2026-5281 |
| 1 de abril de 2026 | Google lança o Chrome 146.0.7680.177/178, 21 vulnerabilidades corrigidas, CVE-2026-5281 confirmada como explorada ativamente |
| 1 de abril de 2026 | CISA adiciona CVE-2026-5281 ao catálogo Known Exploited Vulnerabilities |
| 3 de abril de 2026 | Google reconhece exploração ativa contra 3,5 bilhões de usuários do Chrome |
O mesmo pesquisador pseudônimo que relatou a CVE-2026-5281 também relatou outras três vulnerabilidades no mesmo período (CVE-2026-4675, CVE-2026-4676, CVE-2026-5284, as duas últimas também UAFs na Dawn). Isso sugere um esforço de pesquisa focado e contínuo, direcionado especificamente ao gerenciamento de memória da Dawn.
O toolkit neste repositório foi construído sobre pesquisa de segurança original que documenta o comportamento da vulnerabilidade em ambiente de laboratório. A seguir, um resumo dessa pesquisa, a estratégia usada para acionar o UAF e os resultados observados.
A abordagem do pesquisador para acionar o UAF foi projetada para satisfazer simultaneamente as três condições que tornam a janela de corrida alcançável: pressão suficiente na fila da GPU para atrasar a execução, temporização suficientemente precisa entre destroy e dispatch, e realocação de buffers do mesmo tamanho para maximizar a chance de corrupção observável.
A estratégia se divide em cinco etapas:
Etapa 1 - Volume e pressão: 200 buffers de armazenamento temporários do WebGPU alocados com tamanhos aleatórios (todos múltiplos de 4 bytes, conforme exigido pela especificação do WebGPU). Não se trata de preencher a VRAM, mas sim de criar trabalho pendente suficiente para que a GPU não consiga executar os comandos imediatamente.
Etapa 2 - Saturação dos threads de computação: 32 pipelines de computação paralelos enfileirados com cargas de trabalho pesadas, loops internos executando 1000 iterações e tamanhos de dispatch de 4096 workgroups. O objetivo é manter a fila da GPU profundamente acumulada para que a janela entre o envio e a execução permaneça aberta por tempo suficiente para a corrida.
Etapa 3 - A armadilha: Imediatamente após enviar todos os command buffers, destroy() é chamado em todos os 200 buffers. Nesse ponto, a GPU recebeu os comandos, mas ainda não os executou. A Dawn já passou pela validação no momento do envio. A VRAM é liberada.
Etapa 4 - O gatilho: 32 novas alocações de buffers usando exatamente os mesmos tamanhos dos buffers recém-liberados. Se o alocador de VRAM retornar os mesmos endereços físicos, o que geralmente acontece, já que os tamanhos coincidem, os comandos pendentes da GPU agora têm um identificador de hardware apontando para memória que pertence a uma alocação diferente e ativa.
Etapa 5 - Reutilizar comandos enviados: Outra rodada de envios de command buffers usando os buffers recém-alocados. Nesse ponto, há dois conjuntos de comandos na fila referenciando o que antes era a mesma memória, com a GPU ainda processando o primeiro conjunto.
O resultado é um UAF clássico na camada de VRAM: memória liberada sendo ativamente lida pela execução de shaders em andamento.
O pesquisador executou o PoC em uma instalação vulnerável e em uma corrigida do Chrome e observou uma divisão comportamental clara:
Execução vulnerável (Chrome < 146.0.7680.178):``` [INFO] CVE-2026-5281 AGGRESSIVE PoC Loaded [INFO] Initializing WebGPU context... [INFO] WebGPU device initialized [INFO] Starting aggressive UAF attacks... [ERROR] UNCAUGHT GPU ERROR: device lost due to internal error [CRASH] GPU DEVICE LOST: destroyed [CRASH] [!!!] CRASH DETECTED! Check console for details.
O processo do Chrome alvo parou completamente de renderizar. O sistema operacional sofreu um breve congelamento visual, consistente com o driver de exibição tendo que redefinir ou interromper o processamento após a falha de GPU. O evento de perda de dispositivo foi mapeado para um erro fatal de GPU em vez de um erro padrão de validação da API WebGPU, o que confirma que o layout de memória corrompido atingiu a camada de hardware sem ser capturado pela sandbox do lado JavaScript do Chrome.
**Execução corrigida (Chrome >= 146.0.7680.178):**```
[INFO] CVE-2026-5281 AGGRESSIVE PoC Loaded
[INFO] Initializing WebGPU context...
[INFO] WebGPU device initialized
[INFO] Starting aggressive UAF attacks...
[INFO] Max attempts reached without crash
[INFO] Either browser is patched or target build not affected
Nenhum crash, nenhuma perda de dispositivo, nenhum sinal fatal de GPU em todas as tentativas. A correção se mantém.
As seguintes capturas foram obtidas durante testes de laboratório do kit de ferramentas contra uma instalação vulnerável e uma corrigida do Chrome for Testing em uma máquina Windows com GPU integrada Intel gen-12lp. Cada ferramenta foi executada contra ambos os alvos para verificar a diferença de comportamento.
01 - Detector de Versão
| Vulnerável (< 146.0.7680.178) | Corrigida (>= 146.0.7680.178) |
|---|---|
![]() | ![]() |
02 - Verificador de Vulnerabilidade
| Vulnerável | Corrigida |
|---|---|
![]() | ![]() |
03 - Scanner Local
| Vulnerável | Corrigida |
|---|---|
![]() | ![]() |
04 - Scanner de Frota
| Vulnerável | Corrigida |
|---|---|
![]() | ![]() |
05 - Gatilho de UAF
| Chrome | Firefox |
|---|---|
![]() | ![]() |
O Firefox foi incluído para comparação. O Firefox usa sua própria implementação de WebGPU e não é afetado por esta vulnerabilidade. Ele conclui todas as tentativas sem nenhum sinal de crash, independentemente da versão, o que é o comportamento esperado.
06 - Gatilho de UAF + Executor Automatizado
| GPU Device Lost |
|---|
![]() |
Obter um sinal visível de crash nem sempre é simples. Dependendo do hardware e do ambiente, o gatilho pode exigir alguns ajustes para produzir resultados observáveis. No nosso caso, o comportamento era reproduzível, mas não se manifestava de forma consistente sem ajustar a carga de trabalho.
Reproduzimos com sucesso uma Negação de Serviço contra uma instalação vulnerável do Chrome em um ambiente de laboratório controlado. O gatilho de UAF faz com que a GPU atinja 100% de utilização, pois a fila de comandos fortemente acumulada impede que o driver atenda novas solicitações de gerenciamento de memória. Durante algumas execuções, o processo da GPU entrou em um estado de falha irrecuperável, produzindo os seguintes efeitos observáveis:
A saturação da GPU e a exceção ocasional confirmam que a corrupção de memória está atingindo a camada de hardware: o handle do buffer liberado é acessado pela execução de shaders em andamento, a GPU falha e o mecanismo de TDR do D3D12 o expõe como um evento de remoção de dispositivo. A versão corrigida concluiu a mesma carga de trabalho de forma limpa, sem nenhum tipo de sinal de crash.
A reprodução do DoS confirma a vulnerabilidade. O trabalho em andamento está focado na análise em nível de binário do patch, especificamente no diff do caminho de submissão do command buffer do Dawn entre a última build vulnerável e a 146.0.7680.178, para entender exatamente onde e como a correção de contagem de referências foi aplicada.
Sobre o executor automatizado: o pesquisador original publicou um script de runner junto com seu PoC. Nossa versão exigiu modificações para funcionar de forma confiável em um contexto de laboratório local, especificamente a mudança para o novo modo headless do Chrome e a adição de uma opção para permitir que sinais de crash da GPU sejam propagados do processo da GPU para o processo de renderização. Sem essas duas flags, o Chrome absorve silenciosamente os crashes do processo da GPU e a diferença de comportamento entre as builds vulnerável e corrigida não é observável a partir do JavaScript.
Como o trabalho de engenharia reversa e diff de binários ainda está em andamento, o executor automatizado não está publicado neste repositório. Ele será incluído em uma atualização de acompanhamento assim que a análise do patch for concluída.