Post

CVE-2025-14174 The ANGLE Graphics Bug That Let DarkSword Escape Safari's Sandbox

CVE-2025-14174 The ANGLE Graphics Bug That Let DarkSword Escape Safari's Sandbox

Executive Summary

CVE-2025-14174 is an out-of-bounds write vulnerability in ANGLE (Almost Native Graphics Layer Engine) — the open-source graphics abstraction library used by WebKit/Safari, Google Chrome, and virtually every modern browser to handle WebGL and GPU-accelerated rendering. It served as Stage 3 of the DarkSword exploit chain, providing the critical WebContent sandbox escape by pivoting execution into the GPU process.

What makes CVE-2025-14174 particularly remarkable is its cross-platform reach: ANGLE is a shared component used across browsers and operating systems. The same vulnerability affected Safari on iOS, Google Chrome on Windows/macOS/Linux, Microsoft Edge, and WebKitGTK — a single bug in a graphics library became a universal entry point for sandbox escapes across the entire web ecosystem.

Discovered jointly by Apple Security Engineering and Architecture (SEAR) and Google Threat Analysis Group (GTIG), patched in December 2025, and actively exploited in DarkSword campaigns against targeted individuals in Ukraine, Saudi Arabia, Turkey, and Malaysia.

In DarkSword’s architecture, CVE-2025-14174 was the critical bridge: Stages 1 and 2 gave arbitrary code execution inside the WebContent process. But WebContent is sandboxed — isolated from the rest of the OS. CVE-2025-14174, combined with the PAC bypass from Stage 2 (CVE-2026-20700), broke the sandbox walls and moved execution into the higher-privilege GPU process — setting up the final stages of full kernel compromise.


CVE Summary

FieldDetail
CVE IDCVE-2025-14174
ProductANGLE (Almost Native Graphics Layer Engine) — used in WebKit/Safari and Chrome
Affected PlatformsiOS/iPadOS < 26.2 & < 18.7.3, Safari < 26.2, macOS Sonoma < 14.8.3, Sequoia < 15.7.3, Tahoe < 26.2, Chrome < 143.0.7499.110, Edge (Chromium), WebKitGTK
Vulnerability TypeOut-of-Bounds Write (CWE-787), Memory Buffer Overflow (CWE-119)
CVSS v3.1 Score8.8 (High)
CVSS2 Score10.0 (Critical)
Attack VectorNetwork (malicious WebGL content in browser)
Privileges RequiredNone
User InteractionRequired (visit malicious page)
ImpactArbitrary code execution in GPU process → WebContent sandbox escape
Role in DarkSwordStage 3 — Sandbox escape: WebContent → GPU process
Reported ByApple SEAR + Google Threat Analysis Group (GTIG)
Google Chrome PatchDecember 10, 2025 (Chrome 143.0.7499.110)
Apple PatchDecember 15, 2025 (iOS 26.2, 18.7.3)
CISA KEVYes

What Is ANGLE and Why Is It Everywhere?

The Problem ANGLE Solves

When the web was moving toward GPU-accelerated graphics (WebGL, CSS transforms, canvas effects), browsers faced a critical challenge: OpenGL ES — the standard graphics API used by browsers — is not uniformly supported across operating systems.

  • Windows historically had better support for Direct3D than OpenGL
  • Apple deprecated OpenGL in 2018 and replaced it with Metal
  • Different platforms had wildly different OpenGL driver quality and security

ANGLE (Almost Native Graphics Layer Engine) was Google’s solution: a software layer that accepts OpenGL ES API calls and translates them into the native graphics API of the current platform.

1
2
3
4
5
6
7
8
9
10
11
12
13
Browser JavaScript / WebGL calls
           ↓
    ANGLE (translation layer)
           ↓
    ┌──────────────────────────────┐
    │ Platform-native graphics API │
    │ ● Metal (iOS/macOS)          │
    │ ● Direct3D 11/12 (Windows)   │
    │ ● Vulkan (Linux/Android)     │
    │ ● Desktop OpenGL (fallback)  │
    └──────────────────────────────┘
           ↓
    GPU hardware execution

ANGLE’s Adoption: Everywhere

ANGLE is not a niche library — it is embedded in:

Browser/PlatformANGLE Usage
Google ChromePrimary WebGL/WebGPU backend
Safari / WebKitPrimary GPU rendering backend
Microsoft EdgeInherits from Chrome (Chromium)
FirefoxPartially (on Windows)
Android WebViewCore rendering component
iOS WKWebViewAll web content on iOS
WebKitGTK (Linux)GNOME web browsers

Critical implication: A vulnerability in ANGLE is effectively a cross-browser, cross-platform vulnerability. CVE-2025-14174 affected Chrome users on Windows and macOS at the same time as Safari users on iPhone — all from a single bug in shared code.

ANGLE’s Architecture in WebKit/iOS

In Safari on iOS, ANGLE operates across process boundaries:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
iOS Browser Process Architecture:
─────────────────────────────────

┌─────────────────────────────────────────────────┐
│           Browser Process (UIProcess)           │
│   High privilege — handles navigation, UI       │
└───────────────┬─────────────────────────────────┘
                │ IPC
┌───────────────▼─────────────────────────────────┐
│           WebContent Process                    │
│   Sandboxed — runs JavaScript, HTML, CSS        │
│   ← CVE-2025-31277 / CVE-2025-43529 land here   │
│                                                 │
│   WebGL calls (from JavaScript)                 │
│          ↓                                      │
│   ANGLE (partial — shader compilation)          │
│          ↓ IPC/XPC                              │
└───────────────┬─────────────────────────────────┘
                │ GPU commands via IPC
┌───────────────▼─────────────────────────────────┐
│              GPU Process                        │
│   Higher privilege than WebContent              │
│   Handles actual GPU/Metal rendering            │
│   ANGLE (full — buffer management, rendering)   │
│   ← CVE-2025-14174 lands here                   │
└─────────────────────────────────────────────────┘

The GPU process runs with higher privilege than the WebContent process. It has:

  • Direct access to GPU memory and Metal/rendering APIs
  • Different (broader) sandbox entitlements
  • XPC communication channels to system daemons
  • Access to memory shared between processes

This is why escaping into the GPU process is such a significant stepping stone.


Technical Deep Dive: The Out-of-Bounds Write

Root Cause: Insufficient Bounds Checking in Buffer Operations

CVE-2025-14174 resides in ANGLE’s memory management routines, specifically in the handling of graphics buffer operations. The vulnerability is triggered by manipulating texture parameters through WebGL API calls.

When a WebGL application calls texture-related functions, ANGLE must:

  1. Allocate a buffer of the appropriate size for the texture data
  2. Validate that the provided data fits within the allocated buffer
  3. Copy the data into the buffer for GPU consumption

The bug: in certain code paths, the size calculation used to allocate the buffer did not correctly account for all parameters that determine how much data could be written. This created a window where the write destination buffer was smaller than the write source data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// CONCEPTUAL — simplified vulnerable pattern (NOT actual ANGLE source)

// Attacker controls: width, height, format, type via WebGL API
void uploadTextureData(GLsizei width, GLsizei height, 
                       GLenum format, GLenum type, 
                       const void* pixels) {
    
    // Bug: Size calculated only from primary dimensions
    // Doesn't account for certain format/type combinations
    // that require MORE bytes than width * height * bytesPerPixel
    size_t bufferSize = width * height * getBytesPerPixel(format);
    
    uint8_t* buffer = allocate(bufferSize);
    
    // Actual bytes to copy: may be LARGER than bufferSize
    // due to specific format/type combination
    size_t actualBytes = calculateActualSize(width, height, format, type);
    
    // OOB WRITE: if actualBytes > bufferSize, writes beyond buffer
    memcpy(buffer, pixels, actualBytes);  // ← VULNERABILITY
}

By crafting specific combinations of width, height, format, and type parameters that trigger the miscalculation, an attacker causes ANGLE to write controlled data beyond the allocated buffer — into adjacent heap memory.

The Exploit: From OOB Write to GPU Process Code Execution

Step 1: Heap Grooming in the GPU Process

Since the OOB write occurs in the GPU process (where ANGLE’s buffer management runs), the attacker must first prepare the GPU process heap. This is done by making many WebGL calls that allocate objects of specific sizes — creating a predictable heap layout where the overflow will land on a useful target.

1
2
3
4
5
6
7
8
9
10
11
// CONCEPTUAL — heap grooming via WebGL
const gl = canvas.getContext('webgl2');

// Allocate many objects of controlled sizes to fill gaps
for (let i = 0; i < 1000; i++) {
    const tex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, tex);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, 
                  gl.RGBA, gl.UNSIGNED_BYTE, null);
    // Creates 64*64*4 = 16384 byte texture objects in GPU process heap
}

Step 2: Target Object Placement

After establishing a predictable heap layout, place the target object immediately after a texture buffer that will be overflowed. The target: a C++ object with a vtable pointer — specifically an ANGLE internal object that gets called during rendering.

1
2
3
4
5
6
7
8
9
10
11
Heap layout (attacker-groomed):

[  ANGLE Texture Buffer  ] [  Target C++ Object   ] [  other heap...]
   0x1000      0x2000         0x2000      0x2100

Texture buffer = 0x1000 bytes
  → OOB write at offset 0x1000 → begins writing at 0x2000
  → Target C++ Object header starts at 0x2000
  → vtable pointer at 0x2000+0x00 = 0x2000
  
Attacker writes: new_vtable_ptr = address_of_fake_vtable

Step 3: vtable Pointer Overwrite

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vtable layout for ANGLE renderer object:
  [0x00] = pointer to method_A
  [0x08] = pointer to method_B
  [0x10] = pointer to render() ← this gets called during drawing

After OOB write overwrites vtable pointer:
  object->vtable = &fake_vtable_in_attacker_controlled_memory
  
  fake_vtable[0x10] = attacker_shellcode_address
  
  When ANGLE calls obj->render():
  → Follows fake vtable
  → Calls attacker_shellcode
  → Arbitrary code execution in GPU process

Step 4: Combined with PAC Bypass (CVE-2026-20700)

A crucial detail: on modern iOS with PAC enabled, simply overwriting a vtable pointer is not enough — the vtable pointer itself may be PAC-signed, and the method pointer within must also pass PAC validation.

This is where Stage 2 (CVE-2026-20700) becomes essential. With the PAC/TPRO bypass already applied (from Stage 2), the forged vtable pointer and fake function pointer are accepted by hardware. DarkSword’s Stage 3 relies on Stage 2 having already neutralized PAC — they work in concert.

1
2
3
4
5
6
7
8
9
10
Without Stage 2 (PAC active):
  OOB write overwrites vtable pointer
  → AUTIB instruction checks vtable pointer PAC
  → Invalid PAC (no signing key) → EXCEPTION → CRASH

With Stage 2 (PAC bypassed via CVE-2026-20700):
  OOB write overwrites vtable pointer
  → vtable pointer PAC check skipped/neutralized
  → Fake vtable accepted
  → Code execution in GPU process → SANDBOX ESCAPE

The Sandbox Escape: From WebContent to GPU Process

The purpose of the GPU process sandbox escape is to gain a higher-privilege execution context than the heavily restricted WebContent sandbox allows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
WebContent Process Sandbox:
─────────────────────────────
✗ No filesystem access (most paths)
✗ No network sockets
✗ No XPC to most daemons
✗ No access to private APIs
✗ Heavily restricted entitlements
→ Limited lateral movement capability

GPU Process:
─────────────
✓ Access to Metal GPU APIs
✓ Access to GPU memory (shared with system)
✓ Different sandbox entitlements (broader)
✓ XPC channels to system components
✓ Can communicate with mediaplaybackd (for Stage 4 pivot)
✓ Higher trust level in inter-process communication
→ Significantly more capability for further exploitation

From the GPU process, DarkSword can make XPC calls that the WebContent process cannot, including reaching mediaplaybackd for Stage 4 — the next stepping stone toward kernel access.


Cross-Platform Impact: The Same Bug in Chrome

A unique aspect of CVE-2025-14174: it affected Chrome on Windows/macOS/Linux simultaneously with Safari on iOS.

Google patched it in Chrome 143.0.7499.110 on December 10, 2025, just days before Apple’s patch. This is because both browsers use the same ANGLE codebase — Google’s open-source library maintained at chromium.googlesource.com/angle/angle.

1
2
3
4
5
6
7
8
9
10
11
ANGLE vulnerability discovered by Apple SEAR + Google TAG
                    ↓
Reported to Google (ANGLE maintainer) and Apple simultaneously
                    ↓
┌─────────────────────┐       ┌─────────────────────────┐
│  Google fixes ANGLE │       │  Apple backports fix    │
│  Chrome patched:    │       │  to WebKit's bundled    │
│  Dec 10, 2025       │       │  ANGLE copy:            │
│  v143.0.7499.110    │       │  iOS 26.2, iOS 18.7.3   │
└─────────────────────┘       │  Dec 15, 2025           │
                              └─────────────────────────┘

This cross-platform nature also means the DarkSword-style attack technique could theoretically be applied to Chrome users, not just iPhone users — making CVE-2025-14174 one of the most broadly impactful components of the chain.


Historical Context: ANGLE and WebGL as Attack Surfaces

CVE-2025-14174 continues a pattern of ANGLE/WebGL vulnerabilities being exploited:

CVEYearTypeBrowser Impact
CVE-2021-305062021WebGL OOBChrome
CVE-2022-06092022ANGLE use-after-freeChrome (zero-day, exploited)
CVE-2022-22942022WebRTC buffer overflowChrome (zero-day)
CVE-2023-47622023ANGLE type confusionChrome
CVE-2024-40582024ANGLE out-of-boundsChrome (zero-day)
CVE-2025-141742025ANGLE OOB writeSafari + Chrome (DarkSword)

The recurring pattern: graphics code is memory-unsafe by tradition. ANGLE is written in C++ and handles enormous amounts of attacker-controlled data (shader code, texture data, buffer objects). The graphics pipeline involves complex buffer management that is historically difficult to make memory-safe without significant performance overhead.

This is also why WebGL is specifically targeted: every canvas element, every CSS 3D transform, every GPU-accelerated animation is a potential surface for ANGLE exploitation.


Detection

For Security Researchers

CVE-2025-14174 exploitation happens in the GPU process on iOS:

1
2
3
4
5
6
7
8
Indicators in device logs:
- GPU process (com.apple.WebKit.GPU) crashes around suspicious Safari sessions
- Abnormal Metal API call patterns from the GPU process
- OOB access markers in ANGLE-related crash traces

iVerify detection:
- Post-exploitation behavioral anomalies detectable after full DarkSword chain
  completes — GPU process pivoting to mediaplaybackd (Stage 4)

Network-Level Detection

1
2
3
4
After Stage 3 succeeds (GPU process escaped into):
- DarkSword rapidly proceeds to Stage 4 and beyond
- Sudden burst HTTPS traffic from device immediately after page load
- Unusual XPC communication patterns (device-level EDR)

For Blue Teams / Enterprise

1
2
3
4
5
6
7
Mobile Threat Defense (MTD):
- Lookout, Zimperium, iVerify — behavioral detection of post-exploitation patterns
- MDM: enforce minimum iOS 18.7.3+ (patches CVE-2025-14174)

Chrome Enterprise:
- Enforce Chrome version 143.0.7499.110+
- Chrome Browser Cloud Management: alert on outdated versions

Mitigation

Patch Status

PlatformFixed Version
iOS / iPadOS18.7.3 (patched Dec 2025)
Safari26.2
macOS Sonoma14.8.3
macOS Sequoia15.7.3
macOS Tahoe26.2
Chrome143.0.7499.110 (Dec 10, 2025)
EdgeCorresponding Chromium-based update
tvOS / watchOS / visionOS26.2

Full DarkSword protection requires iOS 18.7.6 / iOS 26.3.1 — patching all 6 CVEs in the chain.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1. iOS devices: Update to iOS 18.7.6+ / iOS 26.3.1+
   Settings → General → Software Update

2. Chrome users: Update to latest Chrome immediately
   Chrome menu → Help → About Google Chrome → Update

3. macOS: Patch to Sonoma 14.8.3 / Sequoia 15.7.3 / Tahoe 26.2+

4. Lockdown Mode (iOS): Blocks Stage 1 → chain never reaches Stage 3
   Settings → Privacy & Security → Lockdown Mode

5. Enterprise:
   - Chrome Browser Cloud Management: enforce version minimum
   - MDM: block iOS access below 18.7.6
   - Consider disabling WebGL in managed environments (breaks WebGL functionality but removes ANGLE attack surface)

CVE-2025-14174 in the Full DarkSword Architecture

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌─────────────────────────────────────────────────────────────────┐
│                  DARKSWORD FULL CHAIN                           │
│                                                                 │
│  Stage 1a/b: CVE-2025-31277 / CVE-2025-43529                    │
│              JavaScriptCore → Arbitrary R/W in WebContent       │
│                         │                                       │
│  Stage 2: CVE-2026-20700 (dyld PAC/TPRO bypass)                 │
│              Arbitrary code execution in WebContent             │
│                         │                                       │
│  ★ Stage 3: CVE-2025-14174 (ANGLE OOB Write)  ★                 │
│              WebGL texture operation → OOB write                │
│              → vtable corruption in GPU process object          │
│              → (PAC bypass from Stage 2 enables this)           │
│              → Arbitrary code execution in GPU process          │
│              → WebContent sandbox ESCAPED                       │
│                         │                                       │
│  Stage 4: XPC injection → mediaplaybackd pivot                  │
│                         │                                       │
│  Stage 5: CVE-2025-43510 (kernel COW race)                      │
│              Kernel arbitrary memory R/W                        │
│                         │                                       │
│  Stage 6: CVE-2025-43520 (kernel privilege escalation)          │
│              Full ROOT → GHOSTBLADE / GHOSTKNIFE / GHOSTSABER   │
└─────────────────────────────────────────────────────────────────┘

Conclusion

CVE-2025-14174 demonstrates the systemic security risk of shared graphics libraries. ANGLE is a 15-year-old C++ codebase that processes enormous amounts of attacker-controlled data — shader code, buffer descriptions, texture parameters — at high performance. Memory safety in this environment is genuinely difficult.

Its cross-platform nature is both its greatest engineering achievement and its greatest security liability. A single vulnerability research finding by Apple SEAR and Google TAG required simultaneous emergency patches across Chrome, Safari, Edge, WebKitGTK, and every Apple platform — because the vulnerable code lived in one shared place.

In DarkSword’s architecture, CVE-2025-14174 was the “wall breaker” — the exploit that physically moved execution from the restrictive WebContent sandbox into the more capable GPU process. Without it, DarkSword’s Stages 1 and 2 would be confined to the browser’s sandboxed world. With it, the door to system daemons, kernel interfaces, and full device compromise stood open.

The fix? Patch everything. And appreciate that your iPhone’s WebGL canvas animation is passing through a surprisingly complex attack surface every time it renders.


References


This post is intended for security researchers, browser security engineers, and mobile security analysts. Technical details are based on publicly disclosed research.

This post is licensed under CC BY 4.0 by the author.