This is a booby-trapped side door, not a fire through the whole browser
CVE-2026-10893 is a use-after-free in Chrome's Chromoting code path. Google shipped the fix in Chrome 149.0.7827.53 for Linux and 149.0.7827.53/.54 for Windows/Mac in the June 2, 2026 stable release, with early-stable bits landing May 29, 2026. In plain English: if an attacker can feed malformed Chromoting traffic into a vulnerable client, they may be able to turn memory corruption into code execution.
The vendor's Critical label reflects the bug class and possible impact, but for enterprise prioritization that overstates the average fleet risk. This is not a generic browse-to-own renderer bug affecting every employee who opens a tab; it is gated by Chromoting reachability and usage, which sharply narrows the exposed population. That keeps it in HIGH, not CRITICAL, for most 10,000-host environments.
4 steps from start to impact.
Reach a live Chromoting client
- Target is on Chrome earlier than 149.0.7827.53/54
- Chromoting is installed, enabled, or actively used
- Attacker can get traffic or content into that remoting path
- Most enterprise Chrome users never touch Chromoting
- This is not broadly internet-reachable like a server daemon
- User action or an existing remoting relationship is likely required
Deliver malformed remoting data
- Attacker controls the remote side or can tamper with remoting traffic
- Victim session reaches the vulnerable parser/state machine
- No public PoC was found
- Restricted Chromium issue details raise attacker development cost
- Modern TLS/session protections may limit on-path opportunities
Trigger the use-after-free
- Precise malformed input reaches the vulnerable object lifecycle
- Target build and platform behave as expected for the exploit
- UAF exploitation reliability varies by platform and allocator behavior
- Chrome hardening raises the bar for stable code execution
Land code execution and follow-on access
- Exploit achieves instruction control instead of a crash
- Any required sandbox-bypass or post-exec chain is available
- Exact post-exploitation blast radius is unclear because bug details remain restricted
- EDR often catches the noisy second stage even if it misses the initial memory bug
The supporting signals.
| In-the-wild status | No public evidence of active exploitation found, and not listed in CISA KEV as of June 5, 2026. |
|---|---|
| Public PoC availability | No public proof-of-concept located. The Chromium issue for this CVE resolves to a restricted bug URL, which increases attacker development friction. |
| EPSS | 0.00038 from your supplied intel; that is an *extremely low* short-term exploitation probability signal. |
| KEV status | No. There is no CISA KEV entry for CVE-2026-10893. |
| Vendor severity / score | Google lists the bug as Critical in the Chrome 149 stable notes, but publishes no CVSS score. |
| CVSS vector interpretation | No official vector exists. Inference only: the likely shape is roughly AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H *if* attacker-controlled Chromoting traffic is sufficient to trigger the flaw. |
| Affected versions | Vulnerable before the fixed Chrome 149 builds. Vendor release notes show 149.0.7827.53 on Linux and 149.0.7827.53/.54 on Windows/Mac as the patched line. |
| Fixed versions | Patch floor is 149.0.7827.53 (Linux) and 149.0.7827.53/.54 (Windows/Mac). Early-stable bits shipped on 2026-05-29; broad stable notes published on 2026-06-02. |
| Scanning / exposure reality | This is a client-side browser bug, not a listening service. Shodan/Censys/FOFA-style exposure counts are mostly irrelevant; what matters is fleet versioning plus Chromoting usage. |
| Reporting source / disclosure timing | Google says it was reported by Google on 2026-05-14 and publicly listed in the Chrome stable notes on 2026-06-02. Your supplied 2026-06-04 date likely reflects downstream indexing rather than first vendor disclosure. |
noisgate verdict.
The decisive factor is reachability: this bug sits behind the Chromoting feature path, not the normal web browsing path used by every Chrome user. That sharply reduces exposed population even though the underlying bug class is capable of remote code execution.
Why this verdict
- Reachability discount: start from a vendor-style Critical mindset because UAF + possible RCE in Chrome is serious, then cut it down because this is Chromoting-reachable, not every-tab reachable.
- User/session gating: the attacker likely needs the victim to actually use Chrome Remote Desktop / Chromoting or to accept a remoting relationship, which implies a smaller exposed slice of the fleet and likely some user participation.
- Weak threat signal: no KEV listing, no public PoC, and the supplied EPSS 0.00038 all argue against emergency-everywhere behavior.
Why not higher?
This does not look like a blanket browse-to-RCE against the general web surface. The practical prerequisites stack up: Chromoting must be present, reachable, and used in a way the attacker can influence, and that compounds downward pressure on severity.
Why not lower?
It is still a memory-safety RCE-class bug in Chrome, not a cosmetic or low-impact logic flaw. If your environment uses Chrome Remote Desktop for help desk, admin access, contractors, or remote support, the vulnerable subset deserves focused attention because successful exploitation could still end in code execution on a user endpoint.
What to do — in priority order.
- Disable unused Chromoting — If Chrome Remote Desktop or related remoting workflows are not business-critical, turn them off by policy or remove the extension/service on managed endpoints. For a HIGH verdict, deploy this compensating control within 30 days on the subset that does not need remoting.
- Restrict remoting traffic — Limit Chromoting use to approved support workflows, managed identities, and approved egress paths so random endpoints cannot start or receive ad hoc remoting sessions. Apply these controls within 30 days for fleets that must keep the feature enabled.
- Prioritize remoting-enabled hosts — Tag endpoints with Chrome Remote Desktop/Chromoting installed or recently executed and move them to the front of your browser patch wave. This narrows the real risk faster than treating all Chrome endpoints as equally exposed, and it should be operationalized within 30 days.
- Alert on browser crash clusters — Watch for repeated
chromecrashes, remoting-related process starts, and suspicious browser child processes on machines that use support remoting. This will not prevent exploitation, but it gives you a chance to catch failed attempts and noisy second stages within 30 days.
- A WAF does not help; the vulnerable surface is a client-side Chromoting code path, not your web app.
- External attack-surface management will miss the real problem because there is no public listening service to fingerprint on most endpoints.
- Blocking generic inbound internet traffic alone is not enough if the attack rides over approved remoting workflows or attacker-controlled support sessions.
Crowdsourced verification payload.
Run this on the target endpoint itself, or push it through your EDR/live-response framework. Invoke it as python3 check_cve_2026_10893.py on macOS/Linux or py -3 check_cve_2026_10893.py --path "C:\Program Files\Google\Chrome\Application\chrome.exe" on Windows; standard user rights are usually enough because it only reads version metadata and executes --version.
#!/usr/bin/env python3
# check_cve_2026_10893.py
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN
import argparse
import os
import platform
import re
import shutil
import subprocess
import sys
from typing import List, Optional, Tuple
PATCH_FLOOR = (149, 0, 7827, 53)
VERSION_RE = re.compile(r'(\d+)\.(\d+)\.(\d+)\.(\d+)')
def parse_ver(text: str) -> Optional[Tuple[int, int, int, int]]:
m = VERSION_RE.search(text or '')
if not m:
return None
return tuple(int(x) for x in m.groups())
def ver_to_str(ver: Tuple[int, int, int, int]) -> str:
return '.'.join(str(x) for x in ver)
def run_version_cmd(path: str) -> Optional[Tuple[int, int, int, int]]:
try:
cp = subprocess.run([path, '--version'], capture_output=True, text=True, timeout=8)
out = (cp.stdout or '') + ' ' + (cp.stderr or '')
return parse_ver(out)
except Exception:
return None
def read_macos_plist(app_path: str) -> Optional[Tuple[int, int, int, int]]:
plist = os.path.join(app_path, 'Contents', 'Info.plist') if app_path.endswith('.app') else None
if not plist or not os.path.exists(plist):
return None
try:
cp = subprocess.run(['defaults', 'read', plist, 'CFBundleShortVersionString'], capture_output=True, text=True, timeout=8)
if cp.returncode == 0:
return parse_ver(cp.stdout)
except Exception:
pass
return None
def windows_candidates() -> List[str]:
cands = []
envs = [os.environ.get('ProgramFiles'), os.environ.get('ProgramFiles(x86)'), os.environ.get('LocalAppData')]
suffixes = [
r'Google\Chrome\Application\chrome.exe',
r'Chromium\Application\chrome.exe',
r'Microsoft\Edge\Application\msedge.exe'
]
for base in envs:
if not base:
continue
for s in suffixes:
p = os.path.join(base, *s.split('\\'))
if os.path.exists(p):
cands.append(p)
return cands
def macos_candidates() -> List[str]:
return [
'/Applications/Google Chrome.app',
'/Applications/Chromium.app',
'/Applications/Microsoft Edge.app'
]
def linux_candidates() -> List[str]:
names = ['google-chrome', 'google-chrome-stable', 'chromium', 'chromium-browser', 'microsoft-edge', 'microsoft-edge-stable']
found = []
for n in names:
p = shutil.which(n)
if p:
found.append(p)
return found
def detect_candidates(user_path: Optional[str]) -> List[str]:
if user_path:
return [user_path]
system = platform.system().lower()
if 'windows' in system:
return windows_candidates()
if 'darwin' in system:
return macos_candidates()
return linux_candidates()
def get_version(path: str) -> Optional[Tuple[int, int, int, int]]:
if platform.system().lower() == 'darwin' and path.endswith('.app'):
v = read_macos_plist(path)
if v:
return v
path = os.path.join(path, 'Contents', 'MacOS', 'Google Chrome')
if not os.path.exists(path):
path = os.path.join(os.path.dirname(path), 'Chromium')
if not os.path.exists(path):
path = os.path.join(os.path.dirname(path), 'Microsoft Edge')
return run_version_cmd(path)
def main() -> int:
ap = argparse.ArgumentParser(description='Check local browser version against CVE-2026-10893 patch floor')
ap.add_argument('--path', help='Exact browser binary or .app path to inspect')
args = ap.parse_args()
candidates = detect_candidates(args.path)
if not candidates:
print('UNKNOWN: no supported Chrome/Chromium/Edge executable found')
return 2
checked = []
vulnerable = []
patched = []
for c in candidates:
v = get_version(c)
if v is None:
checked.append(f'{c}=unknown')
continue
checked.append(f'{c}={ver_to_str(v)}')
if v < PATCH_FLOOR:
vulnerable.append((c, v))
else:
patched.append((c, v))
if vulnerable:
details = '; '.join(f'{p} -> {ver_to_str(v)}' for p, v in vulnerable)
print(f'VULNERABLE: {details} (patch floor {ver_to_str(PATCH_FLOOR)})')
return 1
if patched:
details = '; '.join(f'{p} -> {ver_to_str(v)}' for p, v in patched)
print(f'PATCHED: {details} (patch floor {ver_to_str(PATCH_FLOOR)})')
return 0
print('UNKNOWN: unable to determine version from candidates: ' + '; '.join(checked))
return 2
if __name__ == '__main__':
sys.exit(main())
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.