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

Use after free in WebRTC in Google Chrome prior to 149

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

This is a bad spark in the browser engine, not yet a clean path to burning down the whole workstation

CVE-2026-10903 is a use-after-free in Chrome's WebRTC stack affecting desktop Chrome before 149.0.7827.53 on Linux and before 149.0.7827.53/54 on Windows and macOS. The vendor description says a remote attacker can use a crafted HTML page to achieve arbitrary code execution inside the renderer sandbox, which means the first-stage win is in the browser process, not a full host takeover by itself.

Google scored it HIGH 8.8, which is defensible if you look only at remote code execution against a massively deployed client. In real enterprise conditions, that score needs a trim: the code exec is explicitly sandboxed, there is no KEV listing, no public exploitation evidence surfaced in primary sources, and the disclosed bug details remain restricted, all of which makes this serious but not an automatic top-of-the-pile emergency.

"Drive-by browser RCEs stay urgent, but sandbox-only impact keeps this below panic level."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Lure the user into hostile WebRTC content

The attacker needs a user on vulnerable Chrome to load a malicious page that exercises WebRTC paths. This is classic browser attack surface: no auth, no local foothold, just content delivery over the web.
Conditions required:
  • Target is running vulnerable Chrome desktop build
  • User visits attacker-controlled or attacker-influenced page
  • WebRTC is available and not disabled by policy
Where this breaks in practice:
  • Requires user interaction (UI:R), even if only a page visit
  • Enterprise URL filtering, browser isolation, or safe browsing can block the lure before the bug is reached
Detection/coverage: No network scanner will see this reliably; detection is mostly browser telemetry, web proxy logs, and enterprise browser version inventory.
STEP 02

Trigger the WebRTC lifetime bug

The exploit has to drive WebRTC into a state where freed memory is later reused. For a reliable weaponized chain, the attacker needs more than a crash: they need stable heap shaping across Chrome version, OS, and architecture.
Conditions required:
  • Reachable vulnerable WebRTC code path
  • Exploit tuned to the victim's Chrome build and platform
Where this breaks in practice:
  • No public proof-of-concept was located
  • Chrome memory-hardening and exploit mitigations raise the bar from crash to controlled code execution
Detection/coverage: Crash telemetry may show anomalous renderer faults, but exploit-vs-crash differentiation is weak without deep endpoint visibility.
STEP 03

Land code execution in the renderer sandbox

If exploitation succeeds, the attacker gets code execution inside Chrome's sandboxed renderer, which is meaningful but constrained. That gives control over the compromised browser process and page context, not immediate native execution with normal user privileges across the OS.
Conditions required:
  • Successful memory-corruption exploitation
  • Renderer process survives long enough for post-exploitation actions
Where this breaks in practice:
  • Sandbox confinement sharply limits direct host impact
  • Site isolation, process boundaries, and broker restrictions complicate data reach and follow-on actions
Detection/coverage: EDR may catch abnormal child processes or suspicious broker interactions after compromise, but many browser-only post-exploitation actions look like normal browser behavior.
STEP 04

Chain to bigger impact or settle for browser-scoped abuse

To turn this into a full workstation compromise, the attacker normally needs a second vulnerability such as a sandbox escape, local privilege escalation, or some separate trusted execution path. Without that second stage, the realistic blast radius is browser-scoped abuse, session theft opportunities, and same-user nuisance rather than immediate domain-wide disaster.
Conditions required:
  • Valuable target workflow in browser session
  • Optional second bug or trusted-path abuse for breakout
Where this breaks in practice:
  • No sandbox escape is included in this CVE
  • Modern EDR, application control, and least-privilege reduce post-sandbox payoff
Detection/coverage: This is where EDR has the best chance: breakout attempts, credential access, abnormal file writes, and process spawning are much louder than the browser crash itself.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo current KEV listing and no primary-source evidence of active exploitation located as of 2026-06-05.
Public PoC statusNo public PoC found. The Chromium issue exists but bug details appear restricted, which is normal until patch adoption improves.
EPSS0.00071 from the user intel block; that is a very low predicted near-term exploitation probability.
KEV statusNot listed in CISA KEV as of 2026-06-05.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H — remote and low-complexity, but it still needs user interaction.
Affected versionsChrome desktop before 149.0.7827.53 on Linux and before 149.0.7827.53/54 on Windows and macOS.
Fixed versionsFixed in the Chrome 149 stable desktop rollout: 149.0.7827.53 (Linux) and 149.0.7827.53/54 (Windows/macOS). Android 149.0.7827.59 states it carries the corresponding desktop security fixes.
Exposure / scanning realityShodan/Censys/FOFA are basically irrelevant here. This is a client-side browser bug, so exposure measurement comes from asset inventory, EDR software inventory, Chrome Enterprise reporting, or endpoint management, not internet scanning.
TimelineBug reported to Google on 2026-04-17; stable desktop fix shipped on 2026-06-02; user-supplied disclosure date is 2026-06-04.
Researcher / reporterReported by c6eed09fc8b174b0f3eebedcceb1e792 per Google's release advisory.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to HIGH (7.4/10)

The decisive downgrade factor is sandbox confinement: Google's own wording limits code execution to the browser sandbox, which materially cuts host-level blast radius compared with a clean workstation RCE. It still stays HIGH because this is a remote, no-auth, drive-by bug in Chrome, one of the most exposed and most widely deployed attacker-fed parsers in the enterprise.

HIGH Affected/fixed version mapping from Google's release advisory
MEDIUM Exploitability estimate, because bug details remain restricted and no public PoC was found

Why this verdict

  • Baseline starts high at 8.8 because the target is Chrome, the attack is remote, and delivery is just hostile web content against a ubiquitous client surface
  • Downgrade for sandbox-only impact: the vendor description explicitly says code execution is *inside a sandbox*, so this is not a full-host compromise on its own
  • Further downward pressure from field reality: no KEV entry, no public exploitation evidence, and an EPSS of 0.00071 argue against treating this like an actively burning browser zero-day

Why not higher?

There is no evidence here of a sandbox escape, and that matters more than the scary phrase "arbitrary code execution" when you're triaging at scale. Without in-the-wild abuse or a public weaponized chain, this is not in the same bucket as a browser bug already being chained to full compromise.

Why not lower?

Do not overcorrect just because the first-stage impact is sandboxed. A remote, unauthenticated, web-delivered memory-corruption bug in Chrome is still prime initial-access material, and Chrome's enterprise exposure population is huge enough that even moderate exploit reliability can turn into real incident volume.

05 · Compensating Control

What to do — in priority order.

  1. Force Chrome auto-update compliance — Use endpoint management or Chrome Enterprise policy to eliminate lagging builds and enforce rapid uptake of 149.0.7827.53+. For a HIGH verdict, get this control in place within 30 days if you do not already have enforced browser updating.
  2. Disable or restrict WebRTC where the business can tolerate it — For kiosks, task-worker pools, admin jump boxes, and other low-media-use populations, reducing WebRTC availability trims reachable attack surface. Treat this as a compensating measure to deploy within 30 days on the highest-risk user groups first.
  3. Put risky browsing behind isolation — Browser isolation, VDI browsing, or remote rendering for unmanaged destinations cuts exploit payoff by moving renderer compromise off the user endpoint. For a HIGH verdict, prioritize deployment to executives, admins, finance, and help desk users within 30 days.
  4. Alert on browser spawn-and-breakout behavior — Tune EDR detections for chrome spawning unusual children, touching credential stores, or writing suspicious binaries. This does not stop the bug, but it improves chances of catching the second-stage breakout and should be tightened within 30 days.
What doesn't work
  • A perimeter vulnerability scanner will not help; this is a client-side browser issue, not a listen-service exposure problem
  • A WAF does not protect endpoints from users browsing to hostile external pages outside your app stack
  • Relying on MFA alone is irrelevant to the bug itself; it may reduce account abuse after session theft, but it does not block renderer compromise
06 · Verification

Crowdsourced verification payload.

Run this on the target endpoint or through your EDR/RMM remote script runner. Invoke it with python3 check_chrome_cve_2026_10903.py; no admin rights are usually needed, but Windows registry reads may work more consistently in a normal user context with local software inventory access.

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

import os
import platform
import re
import shutil
import subprocess
import sys

FIXED = (149, 0, 7827, 53)
VERSION_RE = re.compile(r'(\d+)\.(\d+)\.(\d+)\.(\d+)')


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


def run_and_get_version(cmd):
    try:
        p = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=10)
        return parse_version(p.stdout)
    except Exception:
        return None


def windows_candidates():
    candidates = []
    local = os.environ.get('LOCALAPPDATA', '')
    pf = os.environ.get('PROGRAMFILES', '')
    pf86 = os.environ.get('PROGRAMFILES(X86)', '')
    for path in [
        os.path.join(local, 'Google', 'Chrome', 'Application', 'chrome.exe'),
        os.path.join(pf, 'Google', 'Chrome', 'Application', 'chrome.exe'),
        os.path.join(pf86, 'Google', 'Chrome', 'Application', 'chrome.exe'),
    ]:
        if path and os.path.exists(path):
            candidates.append([path, '--version'])
    return candidates


def mac_candidates():
    candidates = []
    for path in [
        '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
        os.path.expanduser('~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
    ]:
        if os.path.exists(path):
            candidates.append([path, '--version'])
    return candidates


def linux_candidates():
    candidates = []
    for name in ['google-chrome', 'google-chrome-stable', '/opt/google/chrome/google-chrome']:
        resolved = shutil.which(name) if not name.startswith('/') else (name if os.path.exists(name) else None)
        if resolved:
            candidates.append([resolved, '--version'])
    return candidates


def get_version():
    system = platform.system().lower()
    if system == 'windows':
        cmds = windows_candidates()
    elif system == 'darwin':
        cmds = mac_candidates()
    else:
        cmds = linux_candidates()

    for cmd in cmds:
        ver = run_and_get_version(cmd)
        if ver:
            return ver, ' '.join(cmd)
    return None, None


def main():
    ver, source = get_version()
    if not ver:
        print('UNKNOWN: Google Chrome not found or version could not be determined')
        sys.exit(2)

    version_str = '.'.join(str(x) for x in ver)
    if ver >= FIXED:
        print(f'PATCHED: detected Chrome {version_str} via {source}; fixed threshold is 149.0.7827.53+')
        sys.exit(0)
    else:
        print(f'VULNERABLE: detected Chrome {version_str} via {source}; requires 149.0.7827.53+ (Linux) or 149.0.7827.53/54+ (Windows/macOS)')
        sys.exit(1)


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

If you remember one thing.

TL;DR
Monday morning, treat this as a broad browser hygiene push, not a red-alert zero-day drill: pull a version inventory for Chrome across user workstations, prioritize externally browsing user groups, and make sure lagging endpoints are either forced onto 149.0.7827.53+ or have WebRTC/browsing isolation compensations applied. Under the noisgate mitigation SLA, temporary controls for this HIGH issue should be in place within 30 days; under the noisgate remediation SLA, the actual vendor-fixed Chrome build should be deployed everywhere within 180 days.

Sources

  1. Google Chrome Releases - Stable Channel Update for Desktop (June 2, 2026)
  2. Google Chrome Releases - Early Stable Update for Desktop (May 29, 2026)
  3. Google Chrome Releases - Chrome for Android Update (June 2, 2026)
  4. Chromium Security Page
  5. Chromium issue 503422316
  6. Chrome Enterprise and Education release notes
  7. CISA Known Exploited Vulnerabilities Catalog
  8. FIRST EPSS
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.