Security Guide
MCP server WebCodecs API security — codec support fingerprinting, decoder timing side channels, hardware-accelerated payload encoding
The WebCodecs API exposes hardware video and audio codec access to browser JavaScript without any user permission. VideoDecoder.isConfigSupported() probes which hardware codecs the device's GPU supports — revealing GPU generation, silicon vendor, and media capability profile. Codec decode timing side channels measure GPU contention state. VideoEncoder in a Web Worker context provides GPU-accelerated data processing for exfiltration payload preparation. No Permissions-Policy directive controls access to the WebCodecs API.
What WebCodecs exposes and where MCP servers encounter it
The WebCodecs API (Chrome 94+, shipping in most modern browsers) provides low-level access to browser codec implementations — the same decoders and encoders used internally by the browser's media pipeline. Unlike the Media Source Extensions API (which operates on containers) or the MediaStream Recording API (which produces blobs), WebCodecs operates on individual raw video frames (VideoFrame) and encoded chunks (EncodedVideoChunk), making it suitable for real-time video processing, WebRTC encoding pipelines, and in-browser video editing.
MCP clients that display images, handle video content, or run in-browser AI image analysis workflows may load the WebCodecs API as part of legitimate functionality. MCP tool output that can inject JavaScript into the same-origin context where WebCodecs is available gains access to all three attack surfaces described below.
Hardware codec fingerprinting via isConfigSupported()
VideoDecoder.isConfigSupported(config) is a static method that returns whether a specific video codec configuration is supported in hardware on the current device. It accepts a VideoDecoderConfig object with a codec string (e.g., "avc1.640034", "hvc1.1.6.L186.B0", "av01.0.08M.10") and returns whether the codec is supported, and if so, whether the implementation is hardware-accelerated or software-only.
By probing a matrix of codec strings — different H.264 profiles, H.265 levels, AV1 tiers, VP9 profiles — injected JavaScript can determine the device's exact hardware codec support set, which correlates strongly with GPU generation and silicon vendor:
// Hardware codec capability fingerprint — no permission required
async function codecFingerprint() {
const codecs = [
'avc1.640034', // H.264 High L5.2 — high-end mobile and desktop GPUs
'avc1.42001f', // H.264 Baseline L3.1 — almost all hardware
'hvc1.1.6.L186.B0', // H.265 Main10 L6.2 — Apple Silicon, newer Intel/AMD
'hvc1.2.4.L153.B0', // H.265 Main Still — select hardware
'av01.0.08M.10', // AV1 Main 10-bit — Intel 11th gen+, AMD RDNA2+, Apple M1+
'av01.0.05M.08', // AV1 Main 8-bit 4K — GPU generation discriminator
'vp09.02.10.10', // VP9 Profile 2 10-bit — broad support differentiator
];
const results = {};
for (const codec of codecs) {
const { supported, config } = await VideoDecoder.isConfigSupported({ codec });
results[codec] = {
supported,
// 'hardware' | 'software' | 'no-preference' — hardware flag is key
hardwareAcceleration: config?.hardwareAcceleration
};
}
// AV1 hardware + H.265 hardware = Apple Silicon or Intel 11th gen+
// AV1 software only + H.265 software = older Intel, AMD pre-RDNA2, older NVIDIA
// Combination narrows device to within ~5 GPU generations and silicon vendor
navigator.sendBeacon('/track', JSON.stringify(results));
}
Codec support matrix narrows device identity more precisely than User-Agent strings. User-Agent strings are frequently spoofed, rounded, or reduced by browser privacy features. Hardware codec support is a function of the actual GPU silicon and driver stack — it cannot be spoofed without modifying the OS driver. Combined with User-Agent, screen resolution, and timezone, a codec fingerprint can narrow device identity to within tens of thousands of users rather than millions.
Decoder timing side channels
When a VideoDecoder is decoding a fixed-cost synthetic video chunk, the time from submission to the output callback depends on whether the hardware decoder pipeline is contended by other work on the same GPU. This timing variation enables a limited cross-context inference attack: if another tab is using the same hardware decoder (for video playback, WebRTC, or ML inference), decode latency in the attacker's context increases measurably.
| Attack | WebCodecs surface | What it reveals |
|---|---|---|
| Codec support fingerprint | isConfigSupported() matrix |
GPU generation, silicon vendor, media capability profile — precise device ID |
| Decoder timing side channel | VideoDecoder latency measurement |
Hardware decoder contention from other tabs — infers video playback or ML workload |
| Hardware-accelerated payload encoding | VideoEncoder in Web Worker |
GPU-speed encoding of exfiltration data — faster than CPU, smaller profiling footprint |
| VideoFrame pixel exfiltration | VideoFrame.copyTo() to ArrayBuffer |
Copies rendered video frame pixels — potentially captures screen content from a video element |
Permissions-Policy gap and defenses
As of mid-2026, the WebCodecs API does not have a Permissions-Policy feature name. The API is available to any same-origin JavaScript without a header or attribute gate. The architectural defense is cross-origin sandboxed iframe rendering for MCP tool output: injected JavaScript in a cross-origin context cannot access the application's data to encode and exfiltrate, even if the codec APIs themselves remain available.
For MCP clients that legitimately use WebCodecs for in-browser media processing, the risk profile is heightened because the codec pipeline is active and hardware-accelerated, making hardware-based timing side channels more reliable. These deployments benefit most from strict tool output sanitization via DOMPurify and CSP script-src nonces that prevent any injection from reaching the codec API.
SkillAudit findings for WebCodecs API exposure
Audit your MCP server for WebCodecs fingerprinting risks
SkillAudit checks for tool output isolation, codec API exposure, and hardware fingerprinting risks automatically — paste a GitHub URL and get a graded security report in 60 seconds.
Run a free audit →