Medium CVSS 10 webkit OOB CISA KEV 🔧 Commit mapped

Overview

Medium
Severity
10
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionMaliciously crafted web content may be able to break out of Web Content sandbox. This is a supplementary fix for an attack that was blocked in iOS 17.2. (Apple is aware of a report that this issue may have been exploited in an extremely sophisticated attack against specific targeted individuals on versions of iOS before iOS 17.2.)
ComponentWebCore Platform/Graphics
Bug ClassOOB
Tracker285858
Fix commit7d784721e440 (WebKit/WebKit)
CWECWE-787 (Out-of-bounds write)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
CISA KEVListed
CreditedApple
Disclosed2025-03-11

Background

ANGLE
WebKit’s translation layer running WebGL on native GPU APIs; its Metal backend executes in the GPU/WebContent graphics path.
PRIMITIVE_RESTART_FIXED_INDEX
A GL capability controlling primitive-restart in indexed draws; in WebGL2 it is implicitly always on and not app-toggleable, and absent in WebGL1.
WebGL enable/disable
APIs that set GL capabilities; forwarding an implementation-managed capability from untrusted content desynchronizes GL state.

Root Cause Analysis

This is a supplementary fix (exploited in the wild before iOS 17.2) for an out-of-bounds sandbox escape via WebGL primitive-restart state in the ANGLE Metal backend. WebGL exposes enable(cap)/disable(cap); GraphicsContextGLANGLE::enable/disable forwarded the capability straight to GL_Enable/GL_Disable. PRIMITIVE_RESTART_FIXED_INDEX must not be toggled by web content: in WebGL2 it is always enabled and managed by the implementation, and in WebGL1 it does not exist. Allowing content to enable or disable it drove ANGLE/GL into an inconsistent primitive-restart configuration that, combined with index buffers during geometry processing, produced out-of-bounds memory access in the GPU pipeline — a corruption primitive used to break out of the WebContent sandbox.

The fix special-cases the capability: disable(PRIMITIVE_RESTART_FIXED_INDEX) raises InvalidOperation in WebGL2 and returns without forwarding to GL; enable(PRIMITIVE_RESTART_FIXED_INDEX) raises InvalidOperation when NOT in WebGL2 and returns.

The restored invariant is that primitive-restart state is controlled by the implementation per WebGL version, never by untrusted enable/disable calls.

Key insight
WebGL enable/disable forwarded PRIMITIVE_RESTART_FIXED_INDEX — a capability the implementation must manage per WebGL version — straight to GL, letting content desynchronize primitive-restart state into an out-of-bounds condition; rejecting the toggle restores control to the implementation.

Attack Path

  1. Create a WebGL context Open a WebGL1 or WebGL2 context from web content.
  2. Toggle the forbidden capability Call gl.enable/gl.disable(PRIMITIVE_RESTART_FIXED_INDEX), which pre-patch forwarded straight to ANGLE/GL.
  3. Desynchronize primitive-restart state Combined with crafted index buffers, the inconsistent state drives out-of-bounds access in the GPU geometry pipeline.
  4. Escape the sandbox Leverage the OOB corruption to break out of the WebContent sandbox (observed in a sophisticated in-the-wild attack).

Impact Assessment

An out-of-bounds memory-corruption primitive reachable from ordinary WebGL content that was used to escape the WebContent sandbox — the advisory notes exploitation in an extremely sophisticated targeted attack and frames it as a supplementary fix. Despite the ‘medium’ label the real-world impact is sandbox escape, among the most serious outcomes for renderer-reachable bugs.

Changed Functions

FunctionChangeNotes
GraphicsContextGLANGLE::disable
Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp
modified For PRIMITIVE_RESTART_FIXED_INDEX raises InvalidOperation in WebGL2 and returns without forwarding to GL_Disable.
GraphicsContextGLANGLE::enable
Source/WebCore/platform/graphics/angle/GraphicsContextGLANGLE.cpp
modified For PRIMITIVE_RESTART_FIXED_INDEX raises InvalidOperation when not WebGL2 and returns without forwarding to GL_Enable.

Audit Directions

  • Other implementation-managed capabilities
    Audit GraphicsContextGLANGLE::enable/disable and cap-forwarding for other GL capabilities that WebGL1/WebGL2 must manage internally rather than accept from content.
  • WebGL version gating
    Grep for m_isForWebGL2 checks around GL state to find capabilities/queries valid in only one WebGL version that are not gated.

Original Bug Report

The reporter's bug is still restricted on the tracker.