← Back to Feed CACHED · 2026-09-25 16:33:37 · CACHE_KEY CVE-2024-23222
CVE-2024-23222 · CWE-843 · Disclosed 2024-01-23

Apple WebKit JavaScriptCore DFG JIT Type Confusion (Cassowary)

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

A race condition in Safari's JIT compiler hands the keys to the house through an unlocked browser tab

CVE-2024-23222 is a type confusion born from a TOCTOU race in WebKit's JavaScriptCore DFG JIT compiler. The vulnerable function Graph::tryGetConstantProperty() reads a JavaScript property on a background compiler thread, releases its cell lock, and returns a raw heap pointer. Between lock release and next use, the main thread can replace the property and trigger garbage collection, freeing the cell the compiler thread still holds. Attackers shape the heap so the freed cell is reallocated with attacker-controlled data, turning the stale pointer into an arbitrary read/write primitive inside the WebContent sandbox. Every Apple platform shipping WebKit is affected: iOS < 17.3 / < 16.7.5 / < 15.8.7, iPadOS (same), macOS Sonoma < 14.3, macOS Ventura < 13.6.4, macOS Monterey < 12.7.3, Safari < 17.3, tvOS < 17.3, visionOS < 1.0.2, plus WebKitGTK < 2.42.5 and WPE WebKit < 2.42.5 on Linux.

Apple's CVSS 8.8 HIGH is honest. The UI:R (user must visit a page) is the only friction in the CVSS vector, and real-world watering-hole campaigns proved it is trivially satisfied: hidden iframes on compromised Ukrainian retail and finance sites (UNC6353), fraudulent crypto exchanges (UNC6691), and surveillance-vendor infrastructure delivered the exploit silently. The Coruna exploit kit chains this WebKit RCE with sandbox escapes and kernel privilege escalation to achieve full device compromise on iOS 13.0–17.2.1 — and iVerify estimated at least 42,000 iPhones were compromised in the Chinese cybercrime wave alone. This is not a theoretical risk — it is a documented, industrialized attack.

"KEV-listed WebKit zero-day weaponized by three threat actors — the vendor's 8.8 holds up."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Victim navigates to attacker-controlled or compromised page

The attacker lures the target to a page hosting a hidden iframe containing the exploit payload (e.g., group.html or analytics.html in the Coruna kit). In documented campaigns, legitimate Ukrainian retail and finance websites were compromised to serve the iframe only to geofenced iPhone users. No click, download, or dialog is required — the iframe executes automatically.
Conditions required:
  • Victim uses a vulnerable WebKit-based browser (Safari on macOS, any browser on iOS)
  • Victim navigates to a compromised or attacker-controlled site
Where this breaks in practice:
  • MDM-managed fleets with enforced OS minimums above iOS 17.3 / macOS 14.3 are not reachable
  • Apple's Lockdown Mode blocks the exploit entirely by disabling JIT
Detection/coverage: Web proxy / SWG logs showing navigation to known Coruna C2 domains; endpoint telemetry for hidden iframe injection patterns.
STEP 02

JavaScript triggers TOCTOU race in DFG JIT compiler

The payload's JavaScript forces the JIT compiler to constant-fold a property while the main thread replaces it and triggers GC. The freed cell is reallocated with attacker-shaped data, producing a type confusion when the compiler thread dereferences the stale pointer. The weaponized tool is the 'Cassowary' module of the Coruna exploit kit (analyzed by Califio and GTIG).
Conditions required:
  • WebKit < 17.3 with DFG JIT enabled (the default on all Apple platforms)
Where this breaks in practice:
  • The race window is naturally nanosecond-scale on x86_64 (the FuzzySecurity PoC inserts a 500ms sleep for determinism); ARM64's weak memory model makes it reliable on iPhones
Detection/coverage: No signature-based detection for the JIT race itself; behavioral detection of anomalous JSC memory patterns is limited to research builds with AddressSanitizer.
STEP 03

Attacker gains arbitrary R/W in WebContent process

The type confusion is escalated through addrof / fakeobj primitives to achieve full read/write within the renderer sandbox. This is the initial code execution foothold. The attacker can now read and write arbitrary memory within the sandboxed WebContent process but cannot yet access the filesystem, keychain, or kernel.
Conditions required:
  • Successful race in Step 2
Where this breaks in practice:
  • The WebContent process is sandboxed; attacker cannot touch the filesystem, keychain, or kernel without additional exploits
Detection/coverage: Apple's Pointer Authentication (PAC) on A12+ chips complicates but does not prevent exploitation; the Coruna kit includes dedicated PAC bypass modules.
STEP 04

Sandbox escape via chained vulnerability

Coruna chains additional exploits (e.g., CVE-2022-48503, CVE-2023-43000) to break out of the WebContent sandbox into a higher-privilege context. The kit selects the appropriate sandbox escape based on the target device's iOS version. Patching the WebKit RCE alone breaks the entire chain regardless of sandbox escape patch status.
Conditions required:
  • A second, unpatched sandbox-escape vulnerability present on the device
  • iOS version within the kit's supported range (13.0–17.2.1)
Where this breaks in practice:
  • Patching CVE-2024-23222 alone breaks the chain — the entry point is eliminated
  • Devices on iOS 17.3+ are immune even if the sandbox escape CVE remains unpatched
Detection/coverage: Crash logs and sysdiagnose artifacts may show sandbox violation attempts; MDM solutions (Jamf, Intune) can collect these diagnostics.
STEP 05

Kernel privilege escalation and persistent implant

Post-sandbox, the kit deploys kernel exploits (e.g., CVE-2023-32434 'Photon', CVE-2023-38606 'Gallium', both previously seen in Operation Triangulation) to gain kernel read/write, disable security policies, and install a persistent implant with full device access — contacts, messages, photos, microphone, location, and all credentials stored on the device.
Conditions required:
  • Unpatched kernel vulnerability matching the device's iOS version
Where this breaks in practice:
  • Multiple kernel CVEs must be unpatched simultaneously; Apple's Rapid Security Responses patch kernel bugs independently of major OS releases
Detection/coverage: iVerify, Jamf Protect, and Zimperium detect known Coruna implant indicators; Apple's iMessage Contact Key Verification flags device compromise on supported builds.
03 · Compensating Control

1
HIGH 8.8→IGNORE 0.0
SEVERITY REDUCED
Enforce minimum OS version via MDM — Push an MDM compliance policy requiring iOS ≥ 17.3 (or ≥ 16.7.5 for older hardware), macOS ≥ 14.3 (or Ventura ≥ 13.6.4, Monterey ≥ 12.7.3), and Safari ≥ 17.3. Non-compliant devices lose access to corporate resources. Because CVE-2024-23222 is KEV-listed, deploy immediately, within hours.
2
HIGH 8.8→LOW 2.0
SEVERITY REDUCED
Enable Apple Lockdown Mode on high-risk devices — Lockdown Mode disables JIT compilation in WebKit, preventing the DFG race condition from triggering. Deploy via MDM configuration profile to executives, IT admins, and other high-value targets. Some JavaScript-heavy web apps may degrade. Deploy within hours for KEV-listed threat.
3
HIGH 8.8→MEDIUM 5.5
SEVERITY REDUCED
Deploy Mobile Threat Defense on all managed devices — Tools like iVerify, Jamf Protect, Lookout, or Zimperium detect known Coruna implant indicators and post-exploitation behaviors. Does not prevent initial exploitation but provides detection and response. Deploy within 30 days per noisgate HIGH remediation SLA.
4
HIGH 8.8→MEDIUM 6.0
SEVERITY REDUCED
Block known Coruna C2 domains and IOCs at the network edge — Add Coruna-associated domains and IPs to your SWG, DNS sinkhole, and firewall blocklists using IOCs published by GTIG and CERT-UA. Blocks delivery of the exploit payload but does not protect against rotated infrastructure. Deploy within hours.
5
HIGH 8.8→IGNORE 0.0
SEVERITY REDUCED
Upgrade WebKitGTK / WPE WebKit on Linux hosts — For Linux systems using GNOME Web or other WebKitGTK-based applications, update to WebKitGTK ≥ 2.42.5 via your package manager (Debian: apt upgrade webkit2gtk). Deploy within 30 days per noisgate HIGH remediation SLA.
What doesn't work
  • Network-level WAF / IDS signatures. The exploit payload is standard JavaScript over HTTPS. TLS inspection would be required, and even then, the Coruna kit's JavaScript is obfuscated and polymorphic. Generic WAF rules will not catch it.
  • Disabling JavaScript globally. While this prevents exploitation, it breaks virtually all modern web applications and is not viable for a production workforce.
  • VPN-only browsing policies. Routing traffic through a corporate VPN does not inspect or block malicious JavaScript; it only changes the network path. The exploit executes in the browser regardless.
  • Standard file-based antivirus on macOS. Traditional AV does not inspect in-memory JIT compilation artifacts. The exploit operates entirely in memory within the WebContent process and writes no malicious files to disk during the initial RCE phase.
04 · Intelligence Metadata

The supporting signals.

In-the-wild statusConfirmed exploited as zero-day. Weaponized in the Coruna iOS exploit kit (module: Cassowary). Three campaigns: UNC6353 (Russian espionage, Ukraine watering holes, mid-2025), UNC6691 (Chinese cybercrime, fake crypto exchanges, 42K+ devices), unnamed surveillance vendor (Feb 2025). GTIG coordinated remediation with CERT-UA.
Proof-of-conceptPublic. FuzzySecurity/Cassowary-CVE-2024-23222-x86_64 (Linux x86_64 adaptation, requires ASan debug build + 500ms sleep). Full weaponized Coruna kit analyzed by Califio. CIRCL Vulnerability-Lookup aggregates 16 exploitation sightings and 4 published PoCs.
EPSS0.10593 — 90th+ percentile. High predicted exploitation probability, consistent with confirmed in-the-wild use.
KEV statusListed 2024-01-23 (same day as Apple's advisory). Federal agency due date was 2024-02-13.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H = 8.8 HIGH. Network-reachable, low complexity, no privileges, user interaction required. Scope unchanged — impact nominally confined to WebContent sandbox, though real-world chains escape it.
Affected versionsiOS < 17.3 / < 16.7.5 / < 15.8.7, iPadOS (same), macOS Sonoma < 14.3, macOS Ventura < 13.6.4, macOS Monterey < 12.7.3, Safari < 17.3, tvOS < 17.3, visionOS < 1.0.2, WebKitGTK < 2.42.5, WPE WebKit < 2.42.5
Fixed versionsiOS 17.3 / 16.7.5 / 15.8.7, iPadOS 17.3 / 16.7.5 / 15.8.7, macOS Sonoma 14.3, macOS Ventura 13.6.4, macOS Monterey 12.7.3, Safari 17.3, tvOS 17.3, visionOS 1.0.2. Linux: WebKitGTK 2.42.5, WPE WebKit 2.42.5. Debian backport: webkit2gtk 2.42.5-1~deb12u1.
Scanning / exposureNot scannable via Shodan/GreyNoise (client-side browser vuln, not a listening service). Exposure is measured by MDM fleet OS version distribution — any device below fixed OS versions is vulnerable when browsing.
Disclosure date2024-01-22 (Apple advisory), 2024-01-23 (NVD, KEV listing). Coruna kit publicly analyzed March 3, 2026.
Researcher / orgOriginally reported to Apple (reporter not publicly credited). Coruna kit reverse-engineered by Califio, GTIG, iVerify, and CERT-UA. FuzzySecurity produced the public x86_64 PoC adaptation.

Sources.

  1. CISA KEV: CVE-2024-23222 added 2024-01-23
  2. NVD: CVE-2024-23222
  3. Coruna exploit kit — Wikipedia
  4. Califio: Coruna Stage 1 writeup (Cassowary technical analysis)
  5. FuzzySecurity: Cassowary CVE-2024-23222 x86_64 PoC
  6. SOCRadar: Apple zero-day CVE-2024-23222
  7. Help Net Security: Apple fixes actively exploited WebKit zero-day
  8. WebKitGTK Security Advisory WSA-2024-0001
05 · The Call

Final Verdict
= UNCHANGED to HIGH (8.8/10)

Why this verdict

  • KEV-listed zero-day with multi-actor weaponization. Three independent threat groups (UNC6353, UNC6691, a surveillance vendor) deployed this in production campaigns. CISA added it to KEV on day one. This alone floors the verdict at HIGH regardless of friction.
  • Industrialized exploit kit eliminates attacker skill barrier. The Coruna framework packages CVE-2024-23222 as a turnkey module with fingerprinting, geofencing, and automatic chain selection for iOS 13–17.2. An operator does not need to write a single line of exploit code.
  • 42,000+ confirmed device compromises validate real-world impact. iVerify's telemetry from the UNC6691 campaign alone counted at least 42,000 iPhones. This is mass exploitation at scale, not a theoretical PoC.
  • Role multiplier: corporate mobile endpoints. WebKit is the mandatory rendering engine for all iOS browsers and the default engine for Safari on macOS. Corporate iPhones and Macs are used by executives, IT admins, finance, and legal — users with access to email, VPN, SSO tokens, MDM admin consoles, and cloud dashboards. A compromised executive iPhone yields Okta push approvals, VPN credentials, and corporate email. Blast radius is host-level initially but escalates to tenant-level or domain-level via credential theft. WebKit is not a canonically high-value-role component (not a DC, hypervisor, or IdP), so the floor is HIGH, not CRITICAL.
  • Friction: user interaction is near-zero in watering-hole delivery. The CVSS UI:R requirement is satisfied by visiting any compromised page — no click, no download, no dialog. Coruna's hidden iframe means the user's only 'interaction' is navigating to a legitimate-looking website.

Why not higher?

The vulnerability is a client-side browser engine flaw, not a server-side or identity-infrastructure component. Exploitation requires user interaction (visiting a page), a vulnerable OS version, and chaining with separate sandbox-escape and kernel-privesc CVEs for full device compromise. The WebContent sandbox limits the initial blast radius to the renderer process. WebKit does not occupy a canonically high-value deployment role (it is not an IdP, CA, hypervisor, or domain controller), so the CRITICAL floor does not apply.

Why not lower?

KEV listing with confirmed multi-actor exploitation categorically prevents any downgrade below HIGH. The EPSS score (0.10593, 90th+ percentile) independently confirms high exploitation probability. The Coruna kit proves the full chain is reliable and industrialized. Watering holes satisfy UI:R trivially, and 42,000+ confirmed compromises leave zero room for 'theoretical risk' discounting.

06 · Verification

Crowdsourced verification payload.

Run on each macOS or Linux target host (no elevated privileges required). Invoke: bash check_cve_2024_23222.sh. On macOS it checks the Safari and macOS version; on Linux it checks the installed WebKitGTK / WPE WebKit package version. For iOS/iPadOS, query your MDM for device OS versions below 17.3 / 16.7.5 / 15.8.7.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2024_23222.sh
# Checks whether the host is vulnerable to CVE-2024-23222
# (WebKit type confusion in JSC DFG JIT)
# Exit codes: 1 = VULNERABLE, 0 = PATCHED, 2 = UNKNOWN

set -euo pipefail

VULNERABLE=1
PATCHED=0
UNKNOWN=2

# Compare two version strings (returns 0 if $1 >= $2)
version_gte() {
  printf '%s\n%s' "$1" "$2" | sort -t. -k1,1n -k2,2n -k3,3n -C 2>/dev/null
  return $?
}

if [[ "$(uname -s)" == "Darwin" ]]; then
  SAFARI_PLIST="/Applications/Safari.app/Contents/Info.plist"
  if [[ -f "$SAFARI_PLIST" ]]; then
    SAFARI_VER=$(/usr/libexec/PlistBuddy -c 'Print CFBundleShortVersionString' "$SAFARI_PLIST" 2>/dev/null || echo "")
    if [[ -n "$SAFARI_VER" ]]; then
      if version_gte "$SAFARI_VER" "17.3"; then
        echo "PATCHED — Safari $SAFARI_VER >= 17.3"
        exit $PATCHED
      else
        echo "VULNERABLE — Safari $SAFARI_VER < 17.3"
        exit $VULNERABLE
      fi
    fi
  fi
  MACOS_VER=$(sw_vers -productVersion 2>/dev/null || echo "")
  if [[ -n "$MACOS_VER" ]]; then
    MAJOR=$(echo "$MACOS_VER" | cut -d. -f1)
    case "$MAJOR" in
      14)
        if version_gte "$MACOS_VER" "14.3"; then
          echo "PATCHED — macOS $MACOS_VER (Sonoma >= 14.3)"
          exit $PATCHED
        else
          echo "VULNERABLE — macOS $MACOS_VER (Sonoma < 14.3)"
          exit $VULNERABLE
        fi
        ;;
      13)
        if version_gte "$MACOS_VER" "13.6.4"; then
          echo "PATCHED — macOS $MACOS_VER (Ventura >= 13.6.4)"
          exit $PATCHED
        else
          echo "VULNERABLE — macOS $MACOS_VER (Ventura < 13.6.4)"
          exit $VULNERABLE
        fi
        ;;
      12)
        if version_gte "$MACOS_VER" "12.7.3"; then
          echo "PATCHED — macOS $MACOS_VER (Monterey >= 12.7.3)"
          exit $PATCHED
        else
          echo "VULNERABLE — macOS $MACOS_VER (Monterey < 12.7.3)"
          exit $VULNERABLE
        fi
        ;;
      *)
        if [[ "$MAJOR" -ge 15 ]]; then
          echo "PATCHED — macOS $MACOS_VER (post-Sonoma, not affected)"
          exit $PATCHED
        else
          echo "VULNERABLE — macOS $MACOS_VER (EOL, no patch available)"
          exit $VULNERABLE
        fi
        ;;
    esac
  fi
  echo "UNKNOWN — could not determine macOS or Safari version"
  exit $UNKNOWN
elif [[ "$(uname -s)" == "Linux" ]]; then
  WEBKIT_VER=""
  if command -v dpkg-query &>/dev/null; then
    WEBKIT_VER=$(dpkg-query -W -f='${Version}' libwebkit2gtk-4.0-37 2>/dev/null | sed 's/-.*//' || echo "")
    [[ -z "$WEBKIT_VER" ]] && WEBKIT_VER=$(dpkg-query -W -f='${Version}' libwebkit2gtk-4.1-0 2>/dev/null | sed 's/-.*//' || echo "")
  elif command -v rpm &>/dev/null; then
    WEBKIT_VER=$(rpm -q --qf '%{VERSION}' webkit2gtk3 2>/dev/null || echo "")
    [[ "$WEBKIT_VER" == *"not installed"* ]] && WEBKIT_VER=""
  fi
  if [[ -n "$WEBKIT_VER" ]]; then
    if version_gte "$WEBKIT_VER" "2.42.5"; then
      echo "PATCHED — WebKitGTK $WEBKIT_VER >= 2.42.5"
      exit $PATCHED
    else
      echo "VULNERABLE — WebKitGTK $WEBKIT_VER < 2.42.5"
      exit $VULNERABLE
    fi
  fi
  if command -v dpkg-query &>/dev/null; then
    WEBKIT_VER=$(dpkg-query -W -f='${Version}' libwpewebkit-1.0-3 2>/dev/null | sed 's/-.*//' || echo "")
  fi
  if [[ -n "$WEBKIT_VER" ]]; then
    if version_gte "$WEBKIT_VER" "2.42.5"; then
      echo "PATCHED — WPE WebKit $WEBKIT_VER >= 2.42.5"
      exit $PATCHED
    else
      echo "VULNERABLE — WPE WebKit $WEBKIT_VER < 2.42.5"
      exit $VULNERABLE
    fi
  fi
  echo "UNKNOWN — WebKitGTK/WPE WebKit not found on this Linux host"
  exit $UNKNOWN
else
  echo "UNKNOWN — unsupported platform $(uname -s)"
  exit $UNKNOWN
fi