Summary
Hacking via Pictures: Stored XSS via SVG Leading to Account Takeover
Hello everyone! đź‘‹
In this write-up, I want to share an interesting finding: a Stored Cross-Site Scripting (XSS) vulnerability hidden inside a profile picture upload feature.
By simply uploading a malicious SVG image, I was able to execute JavaScript code and steal authentication tokens stored in localStorage, leading to a full Account Takeover.
Let’s dive into how it happened!
The Discovery
While hunting on a program from the BugBounty.sa platform, I focused on the user profile settings. I noticed the application allowed users to upload profile pictures, so I immediately checked if it accepted SVG (Scalable Vector Graphics) files.
During my reconnaissance, I found three critical pieces of information that made this attack possible:
- Storage Mechanism: I inspected the application’s storage and found that the session credentials (authentication tokens) were stored in the browser’s
localStorage. - Same-Origin Hosting: I noticed that uploaded photos were hosted self-hosted on the same domain (e.g.,
[https://redacted.com/photos/...](https://redacted.com/photos/…`)) rather than on a separate CDN or sandbox domain. This is crucial because scripts running inside the image share the same origin as the main application, allowing them to accesslocalStorage.
- Missing CSP: The application had a missing or misconfigured Content Security Policy (CSP), allowing inline scripts to execute. Steps to Reproduce
- Navigate to the Target
I logged into my account and went to the Account Details page.
URL:
[https://](https://my.hcloud.sa/account/details)redacted[.com/account/details](https://my.hcloud.sa/account/details) - Create the Malicious Payload
I set up a listener on webhook.site to capture the stolen data. Then, I created a file named
exploit.svg. Inside this file, I embedded a script to grab thetokenfromlocalStorageand send it to my webhook.
- The Payload:*