← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-10921 · CWE-472 · Disclosed 2026-06-04

Integer overflow in Dawn in Google Chrome prior to 149

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a second lock on the vault door, not the street-facing window

CVE-2026-10921 is an integer overflow in Dawn, Chromium's WebGPU implementation, affecting Google Chrome before 149.0.7827.53. The key qualifier in the vendor description matters more than the bug class: the attacker must already have compromised the renderer process and then use this flaw to push malformed WebGPU/Dawn inputs toward a more privileged process boundary.

Google's HIGH 8.3 label is technically defensible because a compromised renderer to GPU/browser-process memory corruption path is exactly the kind of bug that can become a sandbox-escape building block. But in real enterprise risk terms, this is not initial access and not a clean drive-by; it is a post-compromise chain component with very low EPSS and no KEV listing, so the vendor score overstates the urgency for defenders triaging across 10,000 endpoints.

"Dangerous in exploit chains, but not a day-one fire drill unless the attacker already owns the renderer."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Land code execution in the renderer

The attacker first needs a separate primitive that gives them control of Chrome's renderer process. Tooling here is typically a custom malicious HTML/JS harness or another browser bug, not this CVE itself. Once native control exists inside the sandboxed renderer, the attacker can start forging WebGPU/Dawn command traffic toward more privileged Chrome components.
Conditions required:
  • Victim runs a vulnerable Chrome build before 149.0.7827.53
  • Attacker already has a renderer compromise from another bug or execution path
  • A reachable WebGPU/Dawn code path exists in the victim's build/platform
Where this breaks in practice:
  • This CVE does not provide renderer compromise on its own
  • Modern browser exploit chains need at least one additional bug before this CVE becomes useful
  • Some enterprise fleets reduce reachable attack surface with hardware/feature policy controls
Detection/coverage: Traditional vuln scanners will see browser version drift, but they will not detect whether an attacker has the prerequisite renderer foothold. EDR may only catch the chain if it progresses to abnormal child processes, crash bursts, or sandbox escape behavior.
STEP 02

Abuse Dawn/WebGPU input handling

With renderer control, the attacker weaponizes a crafted WebGPU workload and drives it through Dawn Wire / GPU command buffer paths documented by Chromium's WebGPU research. The goal is to trigger the integer overflow during size, offset, or resource accounting so that downstream memory handling becomes unsafe in a more privileged process.
Conditions required:
  • WebGPU/Dawn path is enabled and reachable on the target platform
  • Attacker can execute JavaScript and/or native logic inside the compromised renderer
  • The vulnerable code path is exposed in the victim's exact Chrome build
Where this breaks in practice:
  • WebGPU paths are complex and exploit reliability can be highly platform-specific
  • Graphics stack behavior varies by OS, GPU, driver, and software rendering path
  • Integer-overflow bugs often need careful heap shaping to move from crash to controlled corruption
Detection/coverage: No strong network signature. Browser crash telemetry, GPU-process instability, and repeated renderer/GPU exception patterns are the practical signals.
STEP 03

Cross the sandbox boundary

If the overflow yields memory corruption in the GPU process or a merged privileged process, the attacker tries to convert that into a sandbox escape. Chromium's own severity guidance treats this class seriously because compromised-renderer-to-higher-privilege memory corruption can break the browser's defense-in-depth model.
Conditions required:
  • Corruption lands in a process with privileges beyond the renderer sandbox
  • The exploit can shape memory precisely enough for useful impact
  • Platform mitigations do not terminate the process before weaponization
Where this breaks in practice:
  • A crash is far easier than reliable code execution
  • Sandboxing, process isolation, CFG/CFI, and allocator hardening all raise exploit cost
  • On many fleets, turning this into durable host compromise still needs another step
Detection/coverage: EDR can sometimes catch abnormal browser crash loops, GPU-process terminations, or sandbox-escape follow-on behavior; vulnerability scanners still only see version-based exposure.
STEP 04

Chain to host-level objectives

A successful exploit chain would then pivot from browser boundary bypass to credential theft, session theft, or host compromise using custom post-exploitation tooling. That final blast radius depends much more on what follows the browser escape than on this integer overflow alone.
Conditions required:
  • Attacker successfully weaponizes the bug into more than a denial-of-service crash
  • The endpoint has valuable sessions, secrets, or reachable follow-on paths
  • Endpoint controls do not contain the post-escape activity
Where this breaks in practice:
  • This CVE alone does not guarantee OS-level execution
  • Credential protections, browser isolation, and EDR can still limit value after exploitation
  • Enterprise blast radius is user-context centric unless the attacker adds further escalation
Detection/coverage: Post-exploit detection shifts to EDR, browser telemetry, identity signals, and suspicious token/session use rather than CVE-specific signatures.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public exploitation evidence located in primary sources reviewed, and not listed in CISA KEV at time of assessment. This materially lowers urgency versus Chrome flaws that arrive with zero-day reporting.
Proof-of-concept availabilityNo public PoC or exploit repo found for CVE-2026-10921 in primary-source review. Expect private exploitability to be plausible for advanced actors because Dawn/WebGPU has known research attention, but there is no public weaponization signal here.
EPSS0.00068 (~0.068%) from the supplied intel, which is very low. The exact percentile was not supplied; based on FIRST's 2026-06-04 EPSS distribution, that score sits roughly in the low-20th percentile *(inference, not a direct API lookup for this CVE)*.
KEV statusNot KEV-listed as of this review. If CISA later adds it, the severity and timeline should be revisited immediately because Chrome chain bugs move fast once public exploit chains stabilize.
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H from the supplied vendor intel. The important real-world translation is: user interaction plus high complexity plus chained exploitation assumptions.
Affected versionsAffected: Google Chrome before 149.0.7827.53 per supplied advisory metadata. Chrome release notes show 149.0.7827.53/.54 as the early stable desktop build and 149.0.7827.53 on Beta for desktop.
Fixed versionsFixed in 149.0.7827.53/.54 for Windows and Mac early stable and 149.0.7827.53 on Beta for Windows/Mac/Linux based on Chrome release pages. For fleet ops, treat 149.0.7827.53 or later as the minimum safe floor unless your channel-specific packaging says otherwise.
Scanning / exposure realityShodan/Censys/FOFA are not meaningful here because this is a client-side browser component, not an internet-listenable service. Exposure is determined by endpoint version inventory and policy state, not external attack-surface scans.
Disclosure date2026-06-04 from the supplied intel. Chrome 149.0.7827.53/.54 was already present in release channels on 2026-05-29, which suggests patch availability closely bracketed disclosure.
Researcher / reportingNo public credit found in the reviewed primary sources. Chrome often withholds details until users are broadly updated, so the absence of attribution here is not unusual.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (6.6/10)

The single biggest severity reducer is the prerequisite: the attacker must already control the renderer process. That means this CVE is best understood as a sandbox-escape building block, not an enterprise-scale initial-access event, and the lack of KEV/public exploitation evidence keeps it out of the top patch queue.

HIGH Assessment that the renderer-compromise prerequisite materially downgrades operational urgency
MEDIUM Assessment of exploit practicality across heterogeneous GPU/driver/platform combinations
MEDIUM Affected-version/fixed-version mapping across Chrome channels from public release notes

Why this verdict

  • Requires prior compromise: this is not unauthenticated remote code execution from the open internet; it assumes the attacker already won code execution inside the renderer.
  • Exposure population narrows hard: every added prerequisite compounds downward pressure — user interaction, a first-stage browser bug, then a reachable Dawn/WebGPU path, then reliable privilege-boundary crossing.
  • Threat intel is quiet: no KEV entry, no public exploit kit/PoC located, and a very low EPSS score all argue against treating this like a break-glass Chrome zero-day.

Why not higher?

If this were exploitable from a malicious page without the renderer-compromise prerequisite, it would stay in HIGH or climb higher because Chrome is ubiquitous and browser compromise is high-value. But once you force the attacker to bring their own renderer RCE first, you have moved from initial-access risk to chain-completion risk.

Why not lower?

It still sits above LOW because the vulnerable component lives in a massively deployed browser and the likely outcome is not just a tab crash; it is a potential sandbox-boundary bypass primitive. Chromium's own security guidance treats compromised-renderer-to-higher-privilege memory corruption as strategically important, so ignoring it would be complacent.

05 · Compensating Control

What to do — in priority order.

  1. Enforce browser auto-update health — Validate that Chrome update services, package repos, and MDM policies are actually advancing endpoints to 149.0.7827.53+. For a MEDIUM noisgate verdict there is no mitigation SLA — go straight to the 365-day remediation window — but auto-update drift is the main operational reason browser bugs linger.
  2. Disable or restrict WebGPU where unused — If your user base does not need WebGPU, use enterprise browser policy or managed configuration to reduce reachability of Dawn attack paths. There is no mitigation SLA for MEDIUM, so treat this as a risk-reduction option for higher-risk user groups rather than a fleet-wide emergency control.
  3. Prioritize high-risk cohorts — Move developers, researchers, executives, help desk, and users who browse untrusted content into the first browser update ring. The bug is most relevant where attackers are likely to chain browser exploits, even though the noisgate severity does not justify an emergency fleet-wide scramble.
  4. Watch for browser crash clusters — Hunt for unusual renderer/GPU-process crash spikes and browser instability after suspicious browsing events. This will not prove exploitation, but it is one of the few practical signals for failed or partially successful chain attempts.
What doesn't work
  • A WAF does not help; this is a client-side browser bug, not a server-side request path problem.
  • Perimeter scanning does not help; Shodan/Censys-style visibility cannot tell you which endpoints have a vulnerable browser build.
  • MFA is good hygiene but irrelevant to preventing the vulnerability trigger itself.
06 · Verification

Crowdsourced verification payload.

Run this on the target endpoint or via your software inventory/remote execution platform. Invoke it with python3 chrome_cve_2026_10921_check.py on macOS/Linux or py chrome_cve_2026_10921_check.py on Windows; it needs standard user privileges only because it reads local application metadata and common install paths.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# CVE-2026-10921 Chrome version check
# Exit codes:
#   0 = PATCHED
#   1 = VULNERABLE
#   2 = UNKNOWN

import os
import platform
import re
import subprocess
import sys
from pathlib import Path

MIN_VERSION = (149, 0, 7827, 53)


def parse_version(s):
    m = re.search(r'(\d+)\.(\d+)\.(\d+)\.(\d+)', s or '')
    if not m:
        return None
    return tuple(int(x) for x in m.groups())


def version_str(v):
    return '.'.join(str(x) for x in v)


def get_windows_versions():
    candidates = [
        r'C:\Program Files\Google\Chrome\Application\chrome.exe',
        r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe',
        os.path.expandvars(r'%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe'),
    ]
    found = []
    try:
        import winreg  # type: ignore
        reg_paths = [
            (winreg.HKEY_CURRENT_USER, r'Software\Google\Chrome\BLBeacon', 'version'),
            (winreg.HKEY_LOCAL_MACHINE, r'Software\Google\Chrome\BLBeacon', 'version'),
            (winreg.HKEY_LOCAL_MACHINE, r'Software\WOW6432Node\Google\Chrome\BLBeacon', 'version'),
        ]
        for hive, path, name in reg_paths:
            try:
                with winreg.OpenKey(hive, path) as k:
                    val, _ = winreg.QueryValueEx(k, name)
                    v = parse_version(str(val))
                    if v:
                        found.append(('registry:' + path, v))
            except OSError:
                pass
    except Exception:
        pass

    for c in candidates:
        if os.path.exists(c):
            try:
                out = subprocess.check_output([
                    'powershell', '-NoProfile', '-Command',
                    f"(Get-Item '{c}').VersionInfo.ProductVersion"
                ], stderr=subprocess.DEVNULL, text=True, timeout=10).strip()
                v = parse_version(out)
                if v:
                    found.append((c, v))
            except Exception:
                pass
    return found


def get_macos_versions():
    candidates = [
        '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
        str(Path.home() / 'Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
    ]
    found = []
    for c in candidates:
        if os.path.exists(c):
            try:
                out = subprocess.check_output([c, '--version'], stderr=subprocess.DEVNULL, text=True, timeout=10).strip()
                v = parse_version(out)
                if v:
                    found.append((c, v))
            except Exception:
                pass
    plist_candidates = [
        '/Applications/Google Chrome.app/Contents/Info.plist',
        str(Path.home() / 'Applications/Google Chrome.app/Contents/Info.plist'),
    ]
    for p in plist_candidates:
        if os.path.exists(p):
            try:
                out = subprocess.check_output(['/usr/libexec/PlistBuddy', '-c', 'Print :KSVersion', p], stderr=subprocess.DEVNULL, text=True, timeout=10).strip()
                v = parse_version(out)
                if v:
                    found.append((p, v))
            except Exception:
                pass
    return found


def get_linux_versions():
    commands = [
        ['google-chrome', '--version'],
        ['google-chrome-stable', '--version'],
        ['chromium-browser', '--version'],
        ['chromium', '--version'],
    ]
    found = []
    for cmd in commands:
        try:
            out = subprocess.check_output(cmd, stderr=subprocess.DEVNULL, text=True, timeout=10).strip()
            v = parse_version(out)
            if v:
                found.append((' '.join(cmd), v))
        except Exception:
            pass
    for p in ['/opt/google/chrome/chrome', '/usr/bin/google-chrome', '/usr/bin/google-chrome-stable']:
        if os.path.exists(p):
            try:
                out = subprocess.check_output([p, '--version'], stderr=subprocess.DEVNULL, text=True, timeout=10).strip()
                v = parse_version(out)
                if v:
                    found.append((p, v))
            except Exception:
                pass
    return found


def dedupe(found):
    seen = set()
    result = []
    for path, ver in found:
        key = (path, ver)
        if key not in seen:
            seen.add(key)
            result.append((path, ver))
    return result


def main():
    system = platform.system().lower()
    if 'windows' in system:
        found = get_windows_versions()
    elif 'darwin' in system:
        found = get_macos_versions()
    else:
        found = get_linux_versions()

    found = dedupe(found)

    if not found:
        print('UNKNOWN: Google Chrome not found or version could not be determined')
        sys.exit(2)

    best = max((ver for _, ver in found))
    best_paths = [path for path, ver in found if ver == best]

    if best >= MIN_VERSION:
        print(f'PATCHED: detected Chrome {version_str(best)} at {best_paths[0]} (minimum safe version {version_str(MIN_VERSION)})')
        sys.exit(0)
    else:
        print(f'VULNERABLE: detected Chrome {version_str(best)} at {best_paths[0]} (requires >= {version_str(MIN_VERSION)})')
        sys.exit(1)


if __name__ == '__main__':
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, treat this as a routine-but-real browser hygiene item, not a war room event: verify endpoint inventory, make sure your managed Chrome rings are moving to 149.0.7827.53+, and spot-check that high-risk user cohorts are not stuck on older builds. For a MEDIUM verdict there is no noisgate mitigation SLA — go straight to the 365-day remediation window under the noisgate remediation SLA, but because Chrome updates are low-friction and this bug can help complete exploit chains, most enterprises should simply fold it into the next normal browser deployment wave rather than letting it age in backlog.

Sources

  1. Chrome Releases: Early Stable Update for Desktop (149.0.7827.53/.54)
  2. Chrome Releases: Chrome Beta for Desktop Update (149.0.7827.53)
  3. Chromium Security Severity Guidelines
  4. Chromium Threat Model and Defenses Against Compromised Renderers
  5. Chromium WebGPU Technical Report
  6. FIRST EPSS API Documentation
  7. CISA Known Exploited Vulnerabilities Catalog
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.