XSS to RCE via Upload File

2 minute read

Published:

Stored XSS and Remote Code Execution (RCE) via File Upload

During an analysis of the web application that we’ll call example.com, I identified two critical vulnerabilities: a Stored XSS and a Remote Code Execution (RCE).

The goal of this article is to describe the process of identifying, demonstrating, and reporting the two vulnerabilities I discovered, highlighting the security issues commonly found in web applications within institutional contexts.

Exploring the Application

Upon accessing example.com, after creating an account and logging in, we are redirected to the homepage.

What immediately caught my attention was the “My Data” section, where a user can enter personal data, links to their social profiles, and even upload files.
In particular, the section that intrigued me the most was this one:

My Data

Here, the user can upload files that will later be displayed by clicking their corresponding blue buttons.

This feature made me think right away about the possibility of bypassing file extension checks. So I began testing by uploading files with extensions different from the allowed ones. After several attempts, I submitted this payload:

Payload XSS

Once the uploaded file was viewed, this was the result:

XSS Triggered

Boom! Stored XSS executed!

Attempting RCE

I didn’t stop there. I wanted to test whether it was possible to execute commands on the machine via a PHP file.
So I attempted to upload a .php file containing the following payload:

Payload RCE

Once the file was displayed, I noticed something strange:

File with .txt

The system automatically appended a .txt to the .php extension, preventing the execution of the code.

After several tests on how to bypass the final .txt, it came to my mind that PHP files can also have other valid extensions (such as .php2, .php3, etc.).
So I tried sending the same payload with the .php2 extension:

Payload PHP2

Once the file was displayed, here was the result:

RCE Triggered

And there it is: PHP code executed successfully!

Conclusion

Both vulnerabilities found (Stored XSS and RCE via file upload) were reported and resolved.
With this post, I want to highlight how important it is to properly validate and sanitize user input, especially in contexts where sensitive data is handled.
I strongly recommend that developers review upload policies, allowed extensions, and correctly implement server-side security mechanisms.

If you have questions, doubts, or want to discuss this analysis, feel free to contact me. 😎