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

Stack buffer overflow in Skia in Google Chrome prior to 149

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

This is a cracked windshield on a fast car: dangerous, but it still takes a second failure to become a wreck

CVE-2026-11024 is a stack buffer overflow in Skia, Chrome's 2D graphics stack, affecting Google Chrome before 149.0.7827.53 on Linux and before 149.0.7827.53/54 on Windows and macOS. The practical trigger is hostile web content rendered by the browser — think a crafted page, image, canvas, or drawing path that steers Skia into corrupting stack memory during rendering.

Reality check: this is serious bug class, moderate enterprise urgency. Unauthenticated remote delivery via the web is the amplifier, but the big brakes are user interaction, exploit reliability on modern Chrome, and the renderer sandbox. Google's own release classifies it as Medium, and that matches the real-world patching story better than the raw phrase *stack buffer overflow* would suggest.

"Remote browser memory corruption matters, but this is still a one-bug, user-driven, sandbox-constrained chain."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Deliver a bespoke Skia trigger page

The attacker needs a crafted HTML page that drives vulnerable Skia rendering behavior, using a bespoke trigger rather than any public exploit kit currently observed. Delivery is straightforward: phishing, malvertising, compromised sites, or any browser session that loads attacker-controlled content. Reference: Google states the bug is reachable by a remote attacker via web content in Chrome versions prior to 149.0.7827.53/54.
Conditions required:
  • Target runs vulnerable Chrome prior to 149.0.7827.53/54
  • User opens attacker-controlled or attacker-influenced web content
  • Chrome sandbox is not the only thing standing between renderer compromise and host compromise
Where this breaks in practice:
  • Requires user interaction or at least page load; it is not a server-side worm path
  • Safe Browsing, mail filtering, web proxying, and browser isolation can block many delivery routes
  • No public PoC or turnkey exploit pack was found during review
Detection/coverage: Very little scanner coverage; this is a client-side trigger path. Detection is mostly indirect through web proxy logs, phishing telemetry, or anomalous browsing destinations.
STEP 02

Hit the vulnerable Skia code path

Once the page renders, the exploit has to drive the exact Skia stack corruption condition. The bug was tracked internally under Chromium bug 497591594, and the Chromium source history shows a Skia roll adding larger buffers and safety checks associated with that bug. That strongly suggests a memory safety fix, but details remain intentionally sparse while exploitability information stays restricted.
Conditions required:
  • Specific rendering path must be reachable on the target platform/build
  • The crafted content must survive parser, layout, and graphics pipeline variation
  • The vulnerable code must execute before any fail-safe aborts or benign crash conditions
Where this breaks in practice:
  • Modern browser rendering paths are brittle targets; exploit reliability often varies across OS, CPU, and build
  • A crash is easier than controlled exploitation
  • Chrome's hardening stack raises the bar substantially
Detection/coverage: Endpoint crash telemetry and browser stability metrics can catch repeated renderer crashes. Signature-based vuln scanners will usually not prove exploitability here.
STEP 03

Convert corruption into renderer code execution

A stack overwrite is not automatically useful; the attacker still needs to turn memory corruption into reliable control of execution inside the renderer process. In modern Chrome that means defeating compiler and platform mitigations, aligning offsets precisely, and often pairing corruption with disclosure primitives or chain-specific gadgeting.
Conditions required:
  • The attacker can shape memory state well enough for controlled exploitation
  • Mitigations such as CFG/CFI/CET/PAC and compiler hardening do not break the chain
  • The payload can run inside the renderer context
Where this breaks in practice:
  • Turning a browser crash into stable exploit code is high-skill work
  • Chrome's memory safety instrumentation and exploit mitigations are designed to make single-bug wins unreliable
  • No in-the-wild exploitation evidence or public exploit chain was found
Detection/coverage: EDR may catch follow-on behaviors, but pure renderer exploitation can be quiet. Crash spikes, unusual Chrome child process behavior, and exploit-protection alerts are your best signals.
STEP 04

Escape the sandbox or settle for limited in-sandbox abuse

Even after a successful renderer compromise, the attacker is still inside Chrome's sandbox unless they chain a second vulnerability or abuse data already reachable in the renderer. Chromium's own security docs are explicit that compromised renderer code runs within a constrained sandbox and that the browser process mediates access to higher-value resources.
Conditions required:
  • A second bug or design weakness is available for sandbox escape or privilege expansion
  • Or the attacker accepts lower-impact abuse limited to renderer-accessible data and session context
Where this breaks in practice:
  • This is the decisive brake on severity: single-bug renderer compromise is not full host compromise
  • A second vulnerability materially narrows the real attacker population
  • Modern enterprise EDR often catches noisier post-exploitation steps even if it misses the initial renderer exploit
Detection/coverage: If a second-stage escape is attempted, EDR and OS exploit protection become far more useful. Browser-side isolation means downstream behavior is often more detectable than the initial trigger.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo public evidence of active exploitation found during review. Google did not include an 'exploit exists in the wild' warning for this CVE in the June 2, 2026 Chrome 149 stable advisory.
KEV statusNot listed in CISA KEV as of review time; no KEV due date applies. Source: CISA KEV Catalog
PoC availabilityNo public PoC located across indexed GitHub/exploit searches for this specific CVE. Current exploitation, if any, should be assumed bespoke rather than commodity.
EPSS0.00032 from the provided intel, which is effectively floor-level exploit prediction pressure. FIRST's API is the authoritative EPSS retrieval path: FIRST EPSS API
Vendor severity / baselineGoogle's Chrome 149 release classifies CVE-2026-11024 as Medium in the advisory list, but no vendor or authority CVSS score/vector was published in the reviewed sources.
CVSS vectorNone published by Google/NVD/CVE record in the sources reviewed, so this assessment is based on attack-path friction rather than inherited scoring.
Affected versionsChrome prior to 149.0.7827.53 (Linux) and prior to 149.0.7827.53/54 (Windows/macOS). Chrome for Android 149.0.7827.59 carries the corresponding desktop security fixes.
Fixed versions149.0.7827.53 on Linux and 149.0.7827.53/54 on Windows/macOS per Google's stable desktop release. Do not assume older Extended Stable builds inherited this specific fix unless your managed channel documentation says so.
Scanning / exposure dataShodan/Censys-style internet census is basically irrelevant here because this is a client-side browser flaw, not an internet-facing service. Exposure is measured by endpoint population and browser version hygiene, not by open-port telemetry.
Disclosure / reporterUser-provided disclosure date is 2026-06-04. Google's release post says the bug was reported by Google on 2026-03-30 and shipped fixed in Chrome 149 stable on 2026-06-02.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to MEDIUM (6.4/10)

The single biggest severity brake is Chrome's renderer sandbox: a successful exploit still lands the attacker in a constrained process unless they chain a second bug. That turns this from a full-blast remote endpoint takeover into a one-bug client-side memory corruption issue with meaningful post-trigger friction.

HIGH Affected version range and fixed version mapping
MEDIUM Exploitability assessment under modern Chrome hardening
MEDIUM No-public-PoC / no-active-exploitation conclusion

Why this verdict

  • Start at serious-but-not-panic: remote memory corruption in a massively deployed browser deserves attention even without a published CVSS.
  • Downward adjustment for user-driven delivery: the attacker needs the victim to render hostile content, which implies phishing, malvertising, or site compromise rather than direct unauthenticated service reachability.
  • Downward adjustment for sandbox containment: a compromised renderer is dangerous, but Chromium explicitly treats renderer compromise as a contained state; full host compromise usually needs a second bug or additional abuse path.
  • Downward adjustment for exploit maturity: no KEV listing, no public PoC, and a floor-level EPSS score mean there is little evidence of current weaponization pressure.
  • Not lower because of ubiquity: Chrome is everywhere, web content is a natural delivery mechanism, and stack corruption bugs can become valuable once chained by a capable actor.

Why not higher?

This is not a clean unauthenticated server-side RCE against an exposed enterprise service. The attacker has to win a client-side, user-driven, modern-browser exploitation problem, and then still deal with sandbox escape or accept lower-impact in-sandbox outcomes.

Why not lower?

Calling it LOW would understate the combination of remote reachability via normal web traffic and a genuine memory-corruption primitive in a highly deployed browser. Even with good mitigations, this remains a plausible foothold bug for targeted phishing and exploit-chain work.

05 · Compensating Control

What to do — in priority order.

  1. Keep Chrome auto-update unblocked — Verify Google Update / managed browser update paths are functioning end-to-end so stale browsers do not linger outside policy. For a MEDIUM verdict there is no mitigation SLA, but this is the highest-value control to reduce exposure while you roll routine browser maintenance.
  2. Preserve the sandbox — Hunt for unsupported launch flags like --no-sandbox, brittle kiosk wrappers, or local hardening exceptions that weaken renderer isolation. There is no mitigation SLA for MEDIUM issues, but this directly preserves the main friction that kept the verdict out of HIGH.
  3. Apply stronger browsing isolation to high-risk users — For admins, finance, executives, and threat-facing teams, route untrusted browsing through remote browser isolation or controlled VDI where feasible. There is no mitigation SLA for MEDIUM issues, so use this as risk reduction where your exposure concentration is highest.
  4. Monitor Chrome crash anomalies — Use EDR, browser telemetry, or helpdesk signals to spot clusters of renderer crashes after visits to the same domains or campaigns. There is no mitigation SLA here, but crash correlation is one of the few practical early-warning signals for exploit development against browser memory bugs.
What doesn't work
  • A WAF does not meaningfully protect endpoints from users browsing hostile content over allowed web channels.
  • Perimeter vulnerability scanning will not tell you much; this is a client/browser version problem, not an exposed network service.
  • MFA is good security hygiene, but it does not stop the memory corruption trigger path itself.
06 · Verification

Crowdsourced verification payload.

Run this on the target endpoint itself, or push it through your endpoint management runner. Invoke with python3 chrome_cve_2026_11024_check.py on macOS/Linux or py -3 .\chrome_cve_2026_11024_check.py on Windows; no admin rights are required unless your local software inventory is locked down.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# CVE-2026-11024 Google Chrome version check
# 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)

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

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

def windows_candidates():
    paths = []
    envs = [os.environ.get('PROGRAMFILES'), os.environ.get('PROGRAMFILES(X86)'), os.environ.get('LOCALAPPDATA')]
    suffixes = [
        r'Google\Chrome\Application\chrome.exe',
    ]
    for base in envs:
        if not base:
            continue
        for suffix in suffixes:
            p = os.path.join(base, *suffix.split('\\'))
            if os.path.exists(p):
                paths.append(p)
    return paths

def mac_candidates():
    return [
        '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
        os.path.expanduser('~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'),
    ]

def linux_candidates():
    names = ['google-chrome', 'google-chrome-stable', 'chromium', 'chromium-browser']
    found = []
    for name in names:
        p = shutil.which(name)
        if p:
            found.append(p)
    return found

def get_version():
    system = platform.system().lower()
    candidates = []
    if 'windows' in system:
        candidates = windows_candidates()
    elif 'darwin' in system:
        candidates = mac_candidates()
    else:
        candidates = linux_candidates()

    for exe in candidates:
        v = run_version([exe, '--version'])
        if v:
            return exe, v
    return None, None

def main():
    path, version = get_version()
    if not version:
        print('UNKNOWN: Could not determine installed Chrome/Chromium version on this host.')
        sys.exit(2)

    product = os.path.basename(path) if path else 'chrome'
    ver_str = '.'.join(str(x) for x in version)
    fixed_str = '.'.join(str(x) for x in FIXED)

    if version < FIXED:
        print(f'VULNERABLE: {product} version {ver_str} is below fixed version {fixed_str}.')
        sys.exit(1)
    else:
        print(f'PATCHED: {product} version {ver_str} is at or above fixed version {fixed_str}.')
        sys.exit(0)

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

If you remember one thing.

TL;DR
By Monday morning, pull a clean version inventory for Chrome across managed endpoints and identify anything still below 149.0.7827.53/54. Because this is MEDIUM, there is noisgate mitigation SLAno mitigation SLA — go straight to the 365-day remediation window — but don't let that become neglect: this is still a browser memory-corruption bug on a ubiquitous client, so use your normal browser maintenance channel to close it out well before the noisgate remediation SLA deadline of 365 days.

Sources

  1. Google Chrome Releases - Stable Channel Update for Desktop (Chrome 149)
  2. Chrome Releases 2026 archive showing CVE-2026-11024 classification
  3. Chromium source commit tied to bug 497591594 (Skia roll with safety checks)
  4. Chrome 149 release notes
  5. Chromium Sandbox FAQ
  6. Chromium docs - Threat model and defenses against compromised renderers
  7. CISA Known Exploited Vulnerabilities Catalog
  8. FIRST EPSS API
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.