Self-XSS via filename + CSRF on contact us ‘multipart/data’ form

2 min readMay 28, 2024


السلام عليكم و رحمة الله قبل كل شيئ ارجو منكم الدعاء لإخواننا في غزة, اللهم أنصرهم نصرا قريبا مؤزرا

Hello everyone, pray for our brothers in Gaza. #Free_Palestine.

In this writeup, I’m going to talk about techniques that I used to get reflected cross-site scripting (RXSS). It was a new experience that I faced, and I learned a lot from it. Let’s start.

In our target,, there is a “Contact Us” form that contains an upload file option to submit a screenshot of your problem. As usual, I checked for reflection by putting a random string like “mchkltxss” and found that it reflected. I tried to inject XSS payloads, but they didn’t work because of HTML encoding.

I switched to Burp Suite for a better view of the request. The name of the file that I uploaded goes into the filename variable. I tried manipulating this variable by putting random text to see if there was any reflection, but there was none initially. Then, I tried putting a random extension, like “helloworld.fakeext”. This reflected an error message containing

The file extension provided ‘helloworld.fakeext’ does not match the expected media types.

So, we have reflection.

I attempted HTML injection, and it worked. However, when I tried alert(document.domain), it didn’t work because the function detected that .domain was an extension. But JavaScript is great and gives us functions that don’t need dots. I used alert(document[‘domain’]), and it worked. But up to this point, it was just self-XSS because the file upload uses a POST request with multipart/form-data encoding.

I tried Burp Suite CSRF PoCs, including the multipart one, and they worked, but the file upload part didn’t. So, it was time for coding. I wrote custom code to handle the file upload via a POST request, and after some tweaks, it worked.

kudos to Sabermohamed about his article that showed me the way of doing.

The js code was dynamically add hidden inputs to a form, convert base64 encoded data into a file, and attach this file to the form. The form is then automatically submitted. Now I had a fully exploitable rXSS.

to read the exploitation code check csrf-file-upload-poc

it was valid and non duplicate in two assets

In conclusion, this experience highlighted the importance of thoroughly testing all input fields and exploring various techniques to check for reflection, rXSS, or HTML injection. It underscored the value of experimenting with different methods and tools. Stay vigilant and keep learning.

الحمد لله الذي علمنا ما لم نكن نعلم وكان فضله — تعالى — علينا عظيما والصلاة والسلام على رسوله الكريم وعلى آله وصحبه





Python Ninja, CTF Player and I Break Into Machines When They Refuse to Have A Peaceful Conversation.