SVG File Upload XSS and XXE Chains
SVG is both an image format and an XML document with active features. Whether an uploaded file becomes dangerous depends on how the product stores, serves, embeds, parses, and converts it. An alert(1) inside a local SVG says nothing about the target.
Map the full processing path first. Upload a benign SVG containing a unique color and filename. Record the upload request, returned object ID, delivery hostname, Content-Type, Content-Disposition, CSP, and the HTML element used to display it.
Rendering context decides XSS
An SVG loaded through <img> is generally constrained from running script in modern browsers. The same file opened as a top-level document, embedded with <object>, or injected inline into HTML may execute script or event handlers. Test the product's actual viewer.
Begin with a visual canary, then a harmless script effect such as changing the SVG title. Try common active surfaces only as needed: <script>, onload, links with active schemes, foreignObject, and animation-driven attributes. Sanitizers treat them differently.
Check origin. Files served from a cookieless media domain with forced attachment may offer little XSS impact. Files rendered inline from the main application origin can access that origin unless CSP or sandboxing stops them. A random storage URL is stronger when another user or administrator predictably opens it.
XXE may happen before delivery
The browser is not the only parser. Thumbnailers, metadata extractors, antivirus bridges, and image-conversion workers may parse XML server-side. Use an external entity that requests a unique listener URL:
<!DOCTYPE svg [
<!ENTITY probe SYSTEM "https://listener.example/svg-4821">
]>
<svg xmlns="http://www.w3.org/2000/svg">
<text>&probe;</text>
</svg>
An outbound hit proves server-side entity resolution. Stop before requesting local files or cloud metadata unless the program explicitly permits that step. DNS-only callbacks can be enough when outbound HTTP is blocked.
Compare original and transformed files. If the service returns a PNG thumbnail, inspect whether the worker fetched external references from <image href>, CSS, fonts, or entities. That may be SSRF rather than XXE; name the primitive the evidence supports.
Useful chains
Stored SVG XSS sharpens when avatars, ticket attachments, or knowledge-base images are viewed by privileged staff. XXE sharpens when the parser can reach internal services or include sensitive output in a generated image. An SVG accepted due to extension checks may also expose a broader upload validation flaw.
Do not bundle unrelated behavior into a theatrical “XSS + XXE + RCE” title. Show each processing stage and only chain stages that actually connect.
Evidence and remediation
Provide the original file, upload request, delivery response, embedding HTML, execution origin, CSP, and listener timestamp. For blind server processing, include a unique callback per attempt so browser fetches cannot be mistaken for worker traffic. Upload from a browser with external loading disabled when isolating the source.
Recommend rasterizing untrusted images with hardened libraries, disabling external XML entities and network access in converters, sanitizing SVG with an allowlist, serving uploads from an isolated origin, and forcing attachment where inline display is unnecessary.
PortSwigger's file-upload material explains why extension and MIME checks are only early gates. With SVG, follow the file all the way from multipart body to the final parser.