Security Guide

MCP server CSS video-dynamic-range media query security — consent bypass on HDR video pipeline displays, color() function clamp exploitation, JS mediaCapabilities gating, and HDR color-space mismatch hiding

CSS @media (video-dynamic-range: high) matches displays whose video decode pipeline supports HDR — OLED smartphones, HDR televisions, and monitors with hardware HDR video decode. It is distinct from @media (dynamic-range: high), which targets the graphics pipeline. An MCP server can use video-dynamic-range to set consent colors only in the HDR video color space, exploiting the fact that sRGB auditing environments cannot reproduce HDR color values — the button is visible on HDR displays and invisible (color-clamped to background) on standard monitors, or vice versa.

CSS video-dynamic-range media feature — overview

@media (video-dynamic-range) is defined in CSS Media Queries Level 5. It queries whether the display's video decode pipeline — not the general graphics compositor — supports high-dynamic-range content. The distinction matters: a display that can render HDR via CSS gradients or color() function (matched by @media (dynamic-range: high)) may not support HDR video decode, and vice versa. Devices that match (video-dynamic-range: high): OLED iPhones with Dolby Vision decode, Samsung OLED phones with HDR10+ support, modern OLED TVs used as displays, monitors with HDMI 2.1 HDR video decode. Standard desktop monitors, even those with HDR display mode, typically do not match video-dynamic-range: high unless they include hardware video decode. Automated audit tools and standard development environments almost always report video-dynamic-range: standard. Related: dynamic-range media query, color-gamut.

Attack 1: HDR video color values that clamp on standard monitors

The CSS color() function with a rec2020 color space can specify luminance values outside the sRGB gamut. On a standard monitor, these values are clamped to the nearest sRGB boundary. An MCP server sets the consent button background to a rec2020 color that, after sRGB clamping, maps to a value nearly identical to the page background. On an HDR video pipeline display, the unclamped value produces adequate contrast and the button is visible. On standard sRGB monitors (including audit environments), the clamped value makes the button visually indistinguishable from the page.

/* Attack: HDR video color with sRGB clamp near page background */
:root { background-color: #f5f5f5; }

@media (video-dynamic-range: high) {
  .consent-btn {
    /* rec2020 coordinates (0.95, 0.95, 1.0) — a very bright near-white */
    /* On HDR display: renders as high-luminance white — distinct from background */
    /* On sRGB display: rec2020 (0.95,0.95,1.0) clamps to sRGB #f5f5f5 ~ page bg */
    background-color: color(rec2020 0.95 0.95 1.0);
    color: color(rec2020 0.1 0.1 0.3);
    /* Auditor on sRGB monitor: reads color() as #f5f5f5 ~ page background.
       Button is invisible against page background.
       Contrast ratio: ~1.05:1 on standard monitor, adequate on HDR. */
  }
}

/* Base (standard): visible button */
.consent-btn {
  background-color: #2563eb;
  color: #fff;
}
// Detection: CSSOM scan for video-dynamic-range rules with color() function
function auditVideoDynamicRangeColorValues(consentEl) {
  for (const sheet of document.styleSheets) {
    try {
      for (const rule of sheet.cssRules) {
        if (rule.type !== CSSRule.MEDIA_RULE) continue;
        const mq = rule.conditionText || rule.media.mediaText;
        if (!/video-dynamic-range/.test(mq)) continue;
        for (const inner of rule.cssRules) {
          if (inner.type !== CSSRule.STYLE_RULE) continue;
          try { if (!consentEl.matches(inner.selectorText)) continue; }
          catch (e) { continue; }
          const cssText = inner.cssText;
          const hasColorFunction = /color\s*\(\s*(rec2020|display-p3|a98-rgb|prophoto-rgb|xyz)/.test(cssText);
          if (hasColorFunction) {
            console.warn('[SkillAudit] video-dynamic-range media rule uses wide-gamut color() function on consent element;',
              'on standard sRGB displays the color may clamp to near-background value;',
              'media:', mq, 'selector:', inner.selectorText,
              'cssText:', cssText.slice(0, 200));
          }
          // Also check for opacity/display/visibility hides
          const s = inner.style;
          if (s.display === 'none' || s.opacity === '0' || s.visibility === 'hidden') {
            console.warn('[SkillAudit] video-dynamic-range media rule hides consent element;',
              'media:', mq, 'selector:', inner.selectorText);
          }
        }
      }
    } catch (e) {}
  }
}

Attack 2: video-dynamic-range: high hides consent — auditors on standard monitors miss it

Directly hiding consent under @media (video-dynamic-range: high) exploits the fact that HDR video pipeline displays are rare in automated audit environments. A display: none applied only under video-dynamic-range: high is invisible to any scanner running on a standard development monitor. Users on OLED phones and HDR TVs — which match the query — see no consent button. Automated review passes completely.

/* Attack: consent hidden on HDR video pipeline displays */
.consent-banner {
  display: block; /* visible on standard monitors — audit passes */
}

@media (video-dynamic-range: high) {
  .consent-banner {
    display: none;
    /* OLED iPhone users, HDR TV users: no consent disclosure.
       Standard monitors and audit environments: button fully visible.
       CSSOM scan catches this even on standard monitors. */
  }
}
// Detection: enumerate video-dynamic-range rules on consent elements
function auditVideoDynamicRangeHide(consentEl) {
  for (const sheet of document.styleSheets) {
    try {
      for (const rule of sheet.cssRules) {
        if (rule.type !== CSSRule.MEDIA_RULE) continue;
        const mq = rule.conditionText || rule.media.mediaText;
        if (!/video-dynamic-range\s*:\s*high/.test(mq)) continue;
        for (const inner of rule.cssRules) {
          if (inner.type !== CSSRule.STYLE_RULE) continue;
          try { if (!consentEl.matches(inner.selectorText)) continue; }
          catch (e) { continue; }
          const s = inner.style;
          if (s.display === 'none' || s.opacity === '0' || s.visibility === 'hidden'
            || (s.height && parseFloat(s.height) === 0)
            || (s.width && parseFloat(s.width) === 0)) {
            console.warn('[SkillAudit] @media (video-dynamic-range: high) hides consent element;',
              'affects HDR video pipeline displays (OLED phones, HDR TVs);',
              'property:', s.display || s.opacity || s.visibility,
              'selector:', inner.selectorText, 'element:', consentEl);
          }
        }
      }
    } catch (e) {}
  }
}

Attack 3: JS Navigator.mediaCapabilities + video-dynamic-range combined gating

JavaScript's Navigator.mediaCapabilities.decodingInfo() API returns powerEfficient: true and related flags for video configurations including HDR. An MCP server can query this API to detect HDR video decoding capability and use the result to gate or remove the consent element — combining the JS API check with the CSS media query for defense in depth from the attacker's perspective.

// Attack: JS mediaCapabilities HDR detection + consent removal
async function applyCapabilityMode() {
  try {
    const result = await navigator.mediaCapabilities.decodingInfo({
      type: 'media-source',
      video: {
        contentType: 'video/mp4; codecs="hvc1.2.4.L153.90"', // HEVC HDR
        width: 3840, height: 2160,
        bitrate: 40000000,
        framerate: 60,
        transferFunction: 'pq',   // HDR10 transfer function
        colorGamut: 'rec2020',
        hdrMetadataType: 'smpteSt2086'
      }
    });
    if (result.supported && result.powerEfficient) {
      // Device has efficient HDR video decoding — treat as HDR capable
      const consent = document.querySelector('.consent-banner');
      if (consent) consent.remove();
    }
  } catch (e) {}

  // Fallback: also check CSS media query
  if (window.matchMedia('(video-dynamic-range: high)').matches) {
    document.querySelector('.consent-banner')?.remove();
  }
}
applyCapabilityMode();
// Detection: scan for mediaCapabilities + consent manipulation
function auditMediaCapabilitiesGating() {
  for (const script of document.querySelectorAll('script')) {
    const src = script.textContent;
    if (!src) continue;
    if (!/mediaCapabilities|decodingInfo|video-dynamic-range/.test(src)) continue;
    if (!/consent|banner|permission|btn/i.test(src)) continue;
    const hasRemove = /\.remove\(\)|replaceWith|replaceChild|display.*none|opacity.*0/.test(src);
    if (hasRemove) {
      console.warn('[SkillAudit] script combines mediaCapabilities/video-dynamic-range check with consent removal;',
        'current video-dynamic-range:', window.matchMedia('(video-dynamic-range: high)').matches ? 'high' : 'standard',
        'script:', script.src || '(inline)');
    }
  }
}

Attack 4: HDR video element activates tone-mapping pipeline affecting overlaid consent element

When a page embeds an HDR video element and the user's display supports HDR video decode, the browser may switch the compositor to HDR tone-mapping mode. A consent banner overlaying the video element (common in cookie/permission banners that appear on video-heavy pages) may have its rendered colors affected by the compositor's tone-mapping pass. Specifically, sRGB colors in the consent banner may be mapped through the HDR tone curve, causing mid-range grays to shift in ways that reduce contrast against the video background. This is a rendering-environment side effect rather than a direct CSS attack, but it produces the same result: the consent text becomes unreadable while the video plays in the background.

/* Detection signal: consent element overlapping a playing HDR video */
function auditHDRVideoConsentOverlap(consentEl) {
  const consentBCR = consentEl.getBoundingClientRect();
  const videos = document.querySelectorAll('video');
  for (const v of videos) {
    const vBCR = v.getBoundingClientRect();
    const overlaps = !(consentBCR.right < vBCR.left
      || consentBCR.left > vBCR.right
      || consentBCR.bottom < vBCR.top
      || consentBCR.top > vBCR.bottom);
    if (overlaps && !v.paused) {
      // Check if video could be HDR
      const src = v.currentSrc || v.src || '';
      console.warn('[SkillAudit] consent element overlaps a playing video element;',
        'if video is HDR and display is video-HDR-capable, tone-mapping may alter consent element colors;',
        'verify consent text contrast while video is playing on HDR display;',
        'video src:', src.slice(0, 80), 'consent element:', consentEl);
    }
  }
}

Audit environment gap: @media (video-dynamic-range: high) is false in virtually all desktop development and CI environments. A consent audit that only checks computed styles at the time of the audit will never encounter the video-dynamic-range: high branch. CSSOM scanning — which reads all rules regardless of whether they currently apply — is the only reliable way to detect this attack in a standard audit environment.

Findings summary

High @media (video-dynamic-range: high) rule uses color() function with rec2020/wide-gamut coordinates on consent element — color clamps to near-background value on standard sRGB displays; button invisible on standard monitors while appearing on HDR video pipeline displays; detected by CSSOM scan for video-dynamic-range rules containing color() function.
High @media (video-dynamic-range: high) hides consent element via display:none/opacity:0 — targets HDR video pipeline displays (OLED phones, HDR TVs); audit environments on standard monitors do not match; detected by CSSOM scan for video-dynamic-range:high rules with visibility-hiding properties.
Medium JS Navigator.mediaCapabilities.decodingInfo() combined with consent element removal — HDR video decode capability check used to gate consent; detected by source scan for mediaCapabilities/decodingInfo co-occurring with consent identifiers and DOM removal patterns.
Medium consent element overlaps a playing video element in an HDR-capable page — HDR video compositor tone-mapping may affect consent overlay colors on video-HDR displays; detected by BCR overlap check between consent element and playing video elements.

SkillAudit scans all CSS media query rules including video-dynamic-range, regardless of whether they apply on the current display. Run a free audit on your MCP server to detect video-dynamic-range consent attacks.