← Back to Feed CACHED · 2026-06-06 02:07:21 · CACHE_KEY CVE-2026-10982
CVE-2026-10982 · CWE-416 · Disclosed 2026-06-04

Google Chrome WebXR use-after-free leading to sandboxed code execution

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

This is a loaded nail gun locked in a side room, not a grenade in the lobby

CVE-2026-10982 is a use-after-free in Chrome's WebXR stack. On affected desktop builds, a malicious site can drive stale-object reuse and obtain arbitrary code execution inside a Chrome sandbox via crafted HTML/JavaScript. Affected versions are Chrome prior to 149.0.7827.53/54 on Windows and macOS, and prior to 149.0.7827.53 on Linux; downstream Chromium-based browsers inherit the issue until they pull the fix.

Google's HIGH/8.8 label is technically fair for memory corruption in a ubiquitous browser, but it overstates enterprise risk as a standalone patching signal. The decisive real-world brakes are: user interaction is required, the vulnerable surface is WebXR rather than baseline HTML parsing, and successful exploitation still lands inside Chrome's sandbox, which materially limits host compromise unless the attacker also has a second bug or settles for in-browser post-exploitation.

"Serious browser memory corruption, but the blast radius is narrowed by sandboxing and WebXR reachability friction"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Deliver a crafted WebXR lure

The attacker hosts a malicious page with JavaScript that exercises the WebXR Device API and gets a victim onto it through phishing, malvertising, chat links, or ad redirection. This is still a browser drive-by pattern, but unlike parser bugs in HTML or media, the page has to reach a more specialized API surface.
Conditions required:
  • Victim uses affected Chrome version
  • Victim browses to attacker-controlled or attacker-influenced page
  • WebXR-relevant code path is reachable on that endpoint
Where this breaks in practice:
  • This is UI:R; no click, no exploit chain
  • Many enterprise fleets have little or no practical WebXR usage
  • WebXR capability can be constrained by browser policy, platform support, or absent hardware/runtime
Detection/coverage: URL filtering, Secure Web Gateway telemetry, and browser crash analytics may catch the lure stage; vulnerability scanners usually only flag version exposure, not exploitability of the WebXR path.
STEP 02

Satisfy WebXR gating and trigger stale-object reuse

The attacker uses WebXR session setup and object lifecycle manipulation to hit the vulnerable free/reuse condition. Per WebXR security controls, immersive sessions are gated by xr-spatial-tracking policy and user intent, and XRSystem.requestSession() is an activation-gated API, so the exploit path must align with Chrome's permission and activation model.
Conditions required:
  • Secure context / trustworthy origin requirements are met
  • Required WebXR permissions/policies are allowed
  • Victim provides the user activation needed to request the session
Where this breaks in practice:
  • User activation is an explicit exploit precondition on this API surface
  • Permissions Policy or enterprise hardening can break the path
  • Exploit reliability must survive allocator hardening and modern browser mitigations
Detection/coverage: EDR will not see this step cleanly unless it causes a renderer/GPU crash; browser telemetry and crash dumps are the best signal.
STEP 03

Get code execution in a sandboxed Chrome process

If the memory corruption is shaped reliably, the attacker achieves arbitrary code execution in the compromised browser process. Chromium's own security model assumes renderer compromise is possible and uses process isolation and sandboxing to keep that execution constrained.
Conditions required:
  • Exploit primitives are reliable enough for code execution
  • Target platform mitigations do not fully break the chain
Where this breaks in practice:
  • No public exploit or root-cause write-up was located, so reliability is unproven in the open
  • Renderer and related sandbox profiles sharply restrict OS and file-system reach
  • Site isolation reduces easy cross-origin blast radius
Detection/coverage: Look for renderer crashes, abnormal chrome child-process behavior, exploit-guard/EDR memory-corruption alerts, or browser sandbox diagnostics anomalies.
STEP 04

Monetize inside-browser access or chain a second bug

At this point the attacker either lives within the browser boundary—stealing tokens/data reachable to that process and origin—or pairs the bug with a sandbox escape for host-level compromise. This second stage is where many vendor scores implicitly assume more impact than the single CVE actually guarantees.
Conditions required:
  • Useful victim session/data is present in-browser
  • Or attacker has a second sandbox-escape / privilege-escalation primitive
Where this breaks in practice:
  • This CVE alone does not promise host takeover
  • Cross-origin and OS-level access are limited by Chrome architecture
  • A follow-on sandbox escape is a separate, harder-to-find dependency
Detection/coverage: Identity telemetry, cookie/session abuse detections, and EDR process/memory analytics are more useful here than perimeter controls.
03 · Compensating Control

1
Enforce browser auto-update — Make sure Chrome/Chromium auto-update is not disabled by policy and that stale channels are surfaced in endpoint management. For a MEDIUM verdict there is no mitigation SLA; use this control where patch lag exists before the 365-day remediation window.
2
Constrain risky browsing paths — Apply Secure Web Gateway, URL reputation, attachment detonation, and high-risk site isolation to reduce malicious-page delivery. There is no mitigation SLA for MEDIUM; treat this as an exposure reducer rather than a substitute for updating.
3
Limit unnecessary XR capability — Where business use does not require it, use enterprise browser policy or platform controls to reduce or disable XR-related access paths and hardware/runtime availability on managed endpoints. This directly attacks the narrowest part of the exploit chain and is worth doing on kiosks, shared workstations, and regulated user groups.
4
Prioritize high-risk cohorts first — If you cannot update the whole fleet at once, start with privileged users, finance, executives, developers, kiosks, and any endpoints with VR/AR hardware or Chromium laggards. There is no mitigation SLA for MEDIUM; this is a risk-based sequencing control ahead of the patch.
What doesn't work
  • A WAF does not help; this is not your server being attacked, it's the user's browser processing hostile web content.
  • Network perimeter scanning does not measure this exposure well because the vulnerable asset is endpoint browser versioning, not an internet-facing service banner.
  • MFA is still valuable overall, but it does not stop renderer compromise or in-browser token theft once the victim is on the malicious page.
04 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public evidence of active exploitation was located, and CISA KEV does not list CVE-2026-10982 as of this assessment.
Proof-of-concept availabilityNo public PoC or exploit repo for CVE-2026-10982 was located in retrieved sources; public exploitability should be treated as unconfirmed.
EPSS0.00071 (~0.071% modeled exploitation probability in 30 days). Percentile was not validated from retrieved sources, but the absolute score is plainly low.
KEV statusNot KEV-listed. That removes the strongest urgency amplifier normally used for browser bugs.
CVSS vector interpretationCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H means network-reachable via web content, low complexity, no auth, but user interaction required and impact scoped to the compromised component.
Affected versionsChrome prior to 149.0.7827.53/54 on Windows and macOS, and prior to 149.0.7827.53 on Linux.
Fixed versionsFix landed in 149.0.7827.53/54 (Windows/macOS) and 149.0.7827.53 (Linux). Chromium-based downstream browsers need their own rebased release cadence checked.
Exposure realityThis is a client-side browser flaw, so Shodan/Censys/FOFA exposure counts are not the right lens. Reachability depends on endpoint fleet versioning plus whether WebXR paths are usable on those endpoints.
Disclosure date2026-06-04 in the provided intel; related Google desktop stable release surfaced on 2026-05-29 with broader advisory pickup on 2026-06-02/03.
Reporter / research creditPublicly retrieved sources did not disclose a reporter or bug credit for this CVE.

Sources.

  1. Chrome Releases: Early Stable Update for Desktop (149.0.7827.53/.54)
  2. Canadian Centre for Cyber Security advisory for Chrome versions prior to 149.0.7827.53/54
  3. Chromium sandbox design documentation
  4. Chromium Site Isolation design document
  5. MDN: WebXR permissions and security
  6. MDN: User activation security model
  7. CISA Known Exploited Vulnerabilities Catalog
  8. FIRST EPSS API documentation
05 · The Call

Final Verdict
↓ DOWNGRADED to MEDIUM (6.0/10)

Why this verdict

  • Downgrade from 8.8 baseline: vendor scoring prices in raw memory-corruption danger, but your fleet risk is materially reduced because the stated outcome is sandboxed-only code execution.
  • Attacker position pressure: the chain is still unauthenticated remote, but it is post-lure and UI:R. That means the attacker needs the victim to browse and interact, which modern SWG, browser reputation, and user controls regularly disrupt.
  • Surface-area pressure: this is WebXR, not core HTML parsing or ubiquitous image/media handling. In real enterprises, only a fraction of endpoints meaningfully expose the full XR path, especially where hardware/runtime support is absent or policy-constrained.
  • Second-bug dependency: to get from 'sandboxed renderer code exec' to durable host compromise, the attacker typically needs a sandbox escape or separate privilege escalation. That missing link is a major downward adjustment.
  • Threat-intel pressure is low: no KEV, no public exploitation evidence, and a very low EPSS mean there is no current attacker-behavior signal pushing this back up.

Why not higher?

Because the CVE does not by itself cross the most important enterprise boundary: the host OS. Chrome's sandbox and site/process isolation are not theoretical controls here; they are the exact reason a renderer-class memory corruption should not automatically inherit the urgency of a full remote host takeover. The WebXR-specific reachability constraint adds another real-world limiter.

Why not lower?

It is still a browser memory corruption bug in a massively deployed client application, and browsers remain an initial-access battleground. A malicious site plus user interaction is a realistic delivery model, and in-browser compromise can still expose sessions, tokens, and sensitive data even without a sandbox escape. So this is not backlog hygiene or ignore-grade noise.

06 · Verification

Crowdsourced verification payload.

Run this on the target endpoint or through your EDR/remote execution tool with a local Python 3 interpreter. Invoke it as python3 chrome_cve_2026_10982_check.py; no admin rights are required. The script looks for common Chrome/Chromium desktop installs, reads the product version, and returns VULNERABLE, PATCHED, or UNKNOWN with exit codes 1, 0, and 2.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# CVE-2026-10982 local exposure check for Chrome/Chromium desktop builds
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

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

FIX_WINDOWS_MAC = (149, 0, 7827, 54)  # .53/.54 released; .54 is safest floor for Win/Mac checks
FIX_LINUX = (149, 0, 7827, 53)
VERSION_RE = re.compile(r'(\d+)\.(\d+)\.(\d+)\.(\d+)')


def parse_version(text):
    if not text:
        return None
    m = VERSION_RE.search(text)
    if not m:
        return None
    return tuple(int(x) for x in m.groups())


def run_cmd(cmd):
    try:
        p = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
        out = (p.stdout or '') + ' ' + (p.stderr or '')
        return out.strip()
    except Exception:
        return ''


def candidate_commands():
    system = platform.system()
    cmds = []

    if system == 'Windows':
        local = os.environ.get('LOCALAPPDATA', '')
        program_files = os.environ.get('ProgramFiles', '')
        program_files_x86 = os.environ.get('ProgramFiles(x86)', '')
        cmds.extend([
            [str(Path(local) / 'Google/Chrome/Application/chrome.exe'), '--version'],
            [str(Path(program_files) / 'Google/Chrome/Application/chrome.exe'), '--version'],
            [str(Path(program_files_x86) / 'Google/Chrome/Application/chrome.exe'), '--version'],
            [str(Path(program_files) / 'Chromium/Application/chrome.exe'), '--version'],
            [str(Path(program_files_x86) / 'Chromium/Application/chrome.exe'), '--version'],
        ])
    elif system == 'Darwin':
        cmds.extend([
            ['/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', '--version'],
            ['/Applications/Chromium.app/Contents/MacOS/Chromium', '--version'],
            ['/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta', '--version'],
        ])
    else:
        for name in ['google-chrome', 'google-chrome-stable', 'chromium', 'chromium-browser', 'chrome']:
            path = shutil.which(name)
            if path:
                cmds.append([path, '--version'])

    return cmds


def compare(v1, v2):
    return (v1 > v2) - (v1 < v2)


def main():
    system = platform.system()
    fixed = FIX_WINDOWS_MAC if system in ('Windows', 'Darwin') else FIX_LINUX

    findings = []
    for cmd in candidate_commands():
        exe = cmd[0]
        if not os.path.exists(exe) and not shutil.which(exe):
            continue
        out = run_cmd(cmd)
        ver = parse_version(out)
        if ver:
            findings.append((exe, ver, out.strip()))

    if not findings:
        print('UNKNOWN: no supported Chrome/Chromium executable found')
        sys.exit(2)

    # Choose the highest discovered version as the effective browser version.
    findings.sort(key=lambda x: x[1], reverse=True)
    exe, ver, raw = findings[0]

    if compare(ver, fixed) >= 0:
        print(f'PATCHED: {exe} -> {ver[0]}.{ver[1]}.{ver[2]}.{ver[3]} (fixed floor {fixed[0]}.{fixed[1]}.{fixed[2]}.{fixed[3]})')
        sys.exit(0)
    else:
        print(f'VULNERABLE: {exe} -> {ver[0]}.{ver[1]}.{ver[2]}.{ver[3]} (fixed floor {fixed[0]}.{fixed[1]}.{fixed[2]}.{fixed[3]})')
        sys.exit(1)


if __name__ == '__main__':
    main()