This is a peephole in one apartment window, not a master key to the whole building
CVE-2026-11299 is an out-of-bounds read in Chrome's Fonts handling. A user has to be lured into rendering attacker-controlled content, and the bug can then disclose data from the affected renderer process. Google shipped fixes in Chrome 149 on 2026-06-02: desktop builds prior to 149.0.7827.53/54 for Windows/macOS and 149.0.7827.53 for Linux are affected; Android 149 carries the corresponding desktop security fixes.
The supplied 6.5 / MEDIUM baseline overstates operational urgency for enterprise patch queues. Google's own Chrome release entry tags this CVE Low, and that matches reality better: this is an information leak, not code execution; it needs UI:R; there is no KEV listing or public exploitation evidence; and Chrome's sandbox, site isolation, and per-renderer memory boundaries keep the likely blast radius narrow.
4 steps from start to impact.
Deliver malicious web content
- Unauthenticated remote reachability to the victim through the web
- Victim uses affected Chrome/Chromium build
- Victim renders attacker-controlled content
- Requires user interaction rather than direct service exploitation
- Enterprise browsing controls, Safe Browsing, URL filtering, and ad blocking reduce reach
- Browser auto-update shrinks the vulnerable population quickly
Trigger the Fonts out-of-bounds read
- The vulnerable code path is reachable from the rendered content
- The exploit stays stable enough to produce useful disclosure
- Modern browser hardening makes memory disclosure less deterministic
- Exploit reliability can vary by platform, build flags, and renderer state
Extract useful secrets from renderer memory
- Sensitive data is present in the same renderer process
- The leak returns attacker-usable bytes rather than noise
- Chrome Site Isolation and process separation reduce what is co-located in one renderer
- Many enterprises already protect session material with short-lived tokens and MFA
Monetize the leak
- Leaked data includes reusable secrets or sensitive content
- Attacker has a practical follow-on use for the disclosed memory
- MFA, device binding, and token scoping often blunt stolen web material
- Per-user blast radius limits enterprise-wide consequences
The supporting signals.
| In-the-wild status | No public evidence of active exploitation found as of 2026-06-05; not listed in CISA KEV. |
|---|---|
| Proof-of-concept availability | No widely referenced public PoC or weaponized exploit surfaced in the sources reviewed. That sharply lowers urgency versus browser RCEs that get same-day GitHub demos. |
| EPSS | 0.00028 from the prompt intel, which is extremely low expected exploitation probability. Percentile was not confirmed from an authoritative public page in the reviewed sources. |
| KEV status | No. CISA KEV catalog reviewed with no listing for CVE-2026-11299 as of 2026-06-05. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N — easy to trigger once a user lands on content, but UI:R and confidentiality-only impact are the important brakes. |
| Affected versions | Chrome desktop prior to 149.0.7827.53/54 on Windows/macOS and prior to 149.0.7827.53 on Linux. Google published Chrome 149 stable on 2026-06-02. |
| Fixed versions | Upgrade to 149.0.7827.53+ as the safe floor across enterprise inventory; Windows/macOS stable shipped as 149.0.7827.53/54. Distro backports exist; for example, openSUSE maintenance shipped a Chromium fixset including this CVE. |
| Exposure and scanning reality | This is a client-side browser flaw, not an internet-facing daemon. Shodan/Censys/FOFA/GreyNoise are mostly irrelevant; exposure is measured by endpoint browser version inventory, not open ports. |
| Disclosure and reporter | Google's release stream shows the fix on 2026-06-02 and the CVE record surfaced publicly on 2026-06-05. Google credits [email protected], reported 2026-04-14. |
noisgate verdict.
The decisive factor is that this bug is a user-driven information leak in a browser renderer, not a server-side foothold or code-execution primitive. Even at Chrome scale, the combination of UI:R, no exploitation evidence, and per-process blast radius keeps this in backlog territory rather than emergency patch territory.
Why this verdict
- User interaction is mandatory: the attacker cannot hit a listening service; they need a user to render attacker-controlled content first.
- This is disclosure, not execution: the practical outcome is leaked renderer memory, which is materially less dangerous than Chrome sandbox escape or RCE.
- Real-world population narrows fast: Chrome auto-update plus enterprise browser management compresses exposure far faster than on server middleware.
- No threat intel amplifier: no KEV listing, no public campaign reporting, no obvious public PoC, and an EPSS value close to floor.
Why not higher?
A higher rating would need at least one strong amplifier: active exploitation, a public reliable PoC, a sandbox escape chain, or evidence that the leak routinely exposes reusable enterprise secrets. None of that is present here. On top of that, this is post-lure and per-user, not a broad unauthenticated service compromise.
Why not lower?
It is still a remotely triggerable browser memory disclosure in an extremely widespread product. In a 10,000-host estate, someone will eventually browse hostile content, so this is not ignorable. Sensitive renderer memory leaks can become chainable intelligence for a second-stage attack even when they are weak standalone bugs.
What to do — in priority order.
- Enforce browser auto-update — Make sure managed Chrome/Chromium channels are allowed to self-update and restart on the next normal user disruption window. For a LOW verdict there is no mitigation SLA; do this in routine endpoint hygiene because stale browser populations are what turn minor client bugs into recurring exposure.
- Block unmanaged browser versions — Use EDR, MDM, or application control to flag or restrict old Chrome/Chromium builds that fall below 149.0.7827.53. This is the most scalable control for a 10,000-host estate, and for LOW severity it belongs in standard compliance enforcement rather than emergency change.
- Harden the web path — Keep Safe Browsing, DNS/web filtering, and ad/malvertising controls enabled because they cut off the lure stage that this CVE depends on. With no active exploitation evidence, routine maintenance timing is fine; the point is reducing the chance of users ever rendering hostile content.
- Monitor browser crash anomalies — Collect Chrome crash and renderer instability telemetry so a sudden spike around font handling stands out. This will not prevent exploitation, but it can surface testing or unreliable weaponization attempts during the normal backlog window.
- Perimeter firewall rules do not solve this; there is no inbound service to shield because the attack arrives through normal user web browsing.
- Network IPS signatures are weak coverage; memory disclosure through crafted browser content rarely yields durable signatures with good precision.
- MFA does not prevent the bug from triggering; it only reduces value if leaked material later includes reusable session data.
Crowdsourced verification payload.
Run this on the target endpoint or via your software inventory agent to validate the installed Chrome/Chromium version. Invoke with python3 check_chrome_cve_2026_11299.py on Linux/macOS or py check_chrome_cve_2026_11299.py on Windows; standard user rights are usually enough because the script only reads executable metadata.
#!/usr/bin/env python3
# check_chrome_cve_2026_11299.py
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN
import os
import platform
import re
import shutil
import subprocess
import sys
from pathlib import Path
SAFE_FLOOR = (149, 0, 7827, 53)
CANDIDATES = {
'Windows': [
r'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
r'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
r'C:\\Program Files\\Chromium\\Application\\chrome.exe',
r'C:\\Program Files (x86)\\Chromium\\Application\\chrome.exe',
r'C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe',
r'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
],
'Darwin': [
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
'/Applications/Chromium.app/Contents/MacOS/Chromium',
'/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
],
'Linux': [
'/usr/bin/google-chrome',
'/usr/bin/google-chrome-stable',
'/usr/bin/chromium',
'/usr/bin/chromium-browser',
'/snap/bin/chromium',
'/usr/bin/microsoft-edge',
'/usr/bin/microsoft-edge-stable',
],
}
def parse_version(text):
m = re.search(r'(\d+)\.(\d+)\.(\d+)\.(\d+)', text)
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 is_patched(v):
return v >= SAFE_FLOOR
def run_version(path):
try:
p = subprocess.run([path, '--version'], capture_output=True, text=True, timeout=8)
out = (p.stdout or '') + ' ' + (p.stderr or '')
return parse_version(out)
except Exception:
return None
def find_installs():
sysname = platform.system()
found = []
for p in CANDIDATES.get(sysname, []):
if os.path.exists(p):
found.append(p)
for cmd in ['google-chrome', 'google-chrome-stable', 'chromium', 'chromium-browser', 'msedge', 'microsoft-edge', 'microsoft-edge-stable']:
loc = shutil.which(cmd)
if loc and loc not in found:
found.append(loc)
return found
def main():
installs = find_installs()
if not installs:
print('UNKNOWN - no Chrome/Chromium-family executable found')
sys.exit(2)
results = []
for path in installs:
ver = run_version(path)
if ver is None:
results.append((path, None, 'UNKNOWN'))
elif is_patched(ver):
results.append((path, ver, 'PATCHED'))
else:
results.append((path, ver, 'VULNERABLE'))
# Print per-install result
for path, ver, state in results:
if ver is None:
print(f'{state} - {path} - version unreadable')
else:
print(f'{state} - {path} - {version_str(ver)}')
# Overall state: vulnerable wins, else patched if any patched and none vulnerable, else unknown
if any(state == 'VULNERABLE' for _, _, state in results):
sys.exit(1)
if any(state == 'PATCHED' for _, _, state in results):
sys.exit(0)
sys.exit(2)
if __name__ == '__main__':
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.