WebKit WebGPU `importExternalTexture` Cross-Origin Video Frame Leak (CVE-2026-43700)
by dem0ns · 2026-07-05
- Severity
- High
- CVE
- CVE-2026-43700
- Category
- web
- Affected product
- WebKit / Safari (GPUDevice.importExternalTexture WebGPU API)
- Affected versions
- Safari < 26.5.2
- Disclosed
- 2026-07-05
- Patch status
- unpatched
Tags
References
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-06 |
| Author / Researcher | dem0ns |
| CVE / Advisory | CVE-2026-43700 |
| Category | web |
| Severity | High |
| CVSS Score | N/A (not published in source repository) |
| Status | PoC |
| Tags | webkit, safari, webgpu, cross-origin, information-disclosure, same-origin-policy-bypass, external-texture, video |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | WebKit / Safari (GPUDevice.importExternalTexture WebGPU API) |
| Versions Affected | Safari < 26.5.2 |
| Language / Platform | HTML / JavaScript (WebGPU + WGSL shader) |
| Authentication Required | No |
| Network Access Required | Yes (victim must load an attacker-controlled page while an unrelated cross-origin video is reachable) |
Summary
WebKit’s GPUDevice.importExternalTexture({ source: HTMLVideoElement }) imports the current frame of a <video> element as a GPU-sampleable GPUExternalTexture. Prior to the fix, WebKit did not check the video element’s taintsOrigin (cross-origin CORS-tainted) state before allowing the import, so a page could import frames from a cross-origin video loaded without CORS and read the pixel data back through a WGSL shader and copyTextureToBuffer + mapAsync, bypassing the same-origin policy that normally prevents pixel-level access to cross-origin media.
Vulnerability Details
Root Cause
GPUDevice::importExternalTexture did not call an origin-taint check (the eventual fix adds checkVideoElementOriginTaint) on either its cache-hit or newly-created code paths. As a result, a <video> element whose source is cross-origin and loaded without a crossorigin attribute (making it CORS-tainted / taintsOrigin == true) could still be imported as a GPUExternalTexture and sampled by a WGSL fragment shader, instead of the import throwing a SecurityError as required by the WebGPU spec for tainted media sources.
Attack Vector
- Attacker page loads a cross-origin video (e.g. hosted on a different origin, no
crossoriginattribute → tainted) and plays it. - Attacker page requests a WebGPU device/adapter and calls
device.importExternalTexture({ source: video })on the tainted video element. - On vulnerable Safari builds this succeeds instead of throwing
SecurityError. - Attacker renders the external texture through a minimal WGSL shader that samples a single texel, copies the 1x1 render target to a mappable buffer via
copyTextureToBuffer, and reads the RGBA bytes back into JavaScript viabuffer.mapAsync(GPUMapMode.READ). - Repeating this across
requestVideoFrameCallbackticks lets the attacker page reconstruct changing pixel values from the cross-origin video over time, demonstrating genuine frame-level information leakage (not just a static/cached value).
Impact
Cross-origin information disclosure: an attacker web page can extract pixel content from a video hosted on another origin that the victim’s browser has access to (e.g. via cookies/session or simply being loaded), without CORS permission from that origin — a same-origin-policy bypass that could be used to exfiltrate visually-rendered sensitive content (e.g. video calls, protected media, canvas-rendered data piped through a video element).
Environment / Lab Setup
Target: Safari / WebKit < 26.5.2 with WebGPU enabled
Attacker: Two separate web origins — one serving poc.html (attacker page),
one serving a cross-origin video file loaded without CORS headers
Proof of Concept
PoC Script
See
poc.htmlin this folder.
| |
The page loads a cross-origin, non-CORS (tainted) video, calls device.importExternalTexture() on it, and if the call succeeds ([BYPASS]) samples 8 consecutive frames through a WGSL shader, printing the leaked RGBA values ([LEAK #n]) each time — a changing color sequence across frames (the source video cycles red/green/blue/white) proves genuine cross-origin pixel exfiltration. On patched builds (>= 26.5.2) the importExternalTexture call throws SecurityError and the script reports [PATCHED].
Detection & Indicators of Compromise
Signs of compromise:
- Unexpected outbound requests correlating with decoded pixel values from a cross-origin video/canvas source.
- Pages embedding cross-origin
<video>elements withoutcrossorigin/CORS while also using WebGPU external-texture APIs.
Remediation
| Action | Detail |
|---|---|
| Primary fix | Update Safari/WebKit to >= 26.5.2, which adds checkVideoElementOriginTaint to GPUDevice::importExternalTexture (fix commit 67b563b8, WebKit bug 315368) |
| Interim mitigation | Serve sensitive video content with proper CORS headers and avoid embedding untrusted third-party video sources on pages that grant WebGPU access; disable WebGPU where not needed |
References
Notes
Mirrored from https://github.com/dem0ns/CVE-2026-43700 on 2026-07-05.
| |