June 7, 2026
From Self-XSS to Account Takeover: How I Turned a Low-Severity Finding into a Critical…
Introduction
Kanishkdadhich
3 min read
Introduction
While testing an e-commerce platform that allows merchants to create stores and sell products online, I discovered a vulnerability that initially looked almost useless.
It started with a simple broken image payload.
"><img src=x>"><img src=x>It ended with full account takeover.
This is the story of how I converted what looked like self-XSS into a high-impact exploit chain by understanding role interactions inside the platform.
Starting My Research
I created a store account and started exploring the platform's features.
During testing, I found a product upload functionality where merchants could add:
- Product name
- Product description
- Images
- Other product metadata
While testing the product description field, I noticed something unusual.A simple broken image payload executed.That immediately told me:
There might be some form of HTML injection or XSS here.
But for that, I intercepted that request and corrected my payload because there was client-side senetization
Bypassing Protection Mechanisms
At first, only very simple payloads worked.
More advanced payloads were blocked.
So I spent time experimenting with payload variations and filter bypasses until I found a payload that successfully bypassed protection mechanisms and executed reliably.
<details/open/ontoggle=confirm(1)><details/open/ontoggle=confirm(1)>After confirming execution, I started testing the impact.
Why I Initially Thought It Was Self-XSS
The payload execution behavior was strange.
The script did not execute on the public storefront.
It only executed inside the admin panel when editing/viewing that product again.
That meant:
- Public users could not trigger i
- Visitors could not trigger it
- Store pages did not trigger it
- Only admins interacting with product editing pages triggered it
At this stage, I considered it a classic self-XSS issue.
Low impact.
Almost ready to move on.
Trying Multiple Attack Paths
Before discarding the finding, I explored multiple possibilities.
I tested:
- CSRF scenarios
- IDOR
- Store collaboration features ..etc
All ideas failed.
But one feature changed everything.
Discovering the Staff System
The platform allowed store owners to add staff members.
One role immediately caught my attention:
Manager
Managers had permissions to:
- Create products
- Edit products
- Publish products
But they were still lower privilege than store owners.
That created an interesting trust boundary.
The Turning Point
I created two accounts:
Owner Account
Full store access
Manager Account
Limited permissions but product management capabilities. Using the manager account, I created a malicious product. Inside the product description, I inserted my payload. The manager successfully published the product. Now came the important test.
What happens when the owner reviews or edits that product?
From Self-XSS to Stored XSS
When the owner opened the product editing page inside the admin panel:
The payload executed in the owner's browser context.
At this moment, the issue transformed completely.
This was no longer self-XSS.
This became:
Stored XSS across privilege boundaries
A lower-privileged user could now execute JavaScript in a higher-privileged user session.
Impact: Privilege Escalation to Account Takeover
Because the payload executed inside the owner's authenticated context:
- Session information became accessible
- Higher privileged actions became possible
- Store ownership permissions could effectively be inherited
By replacing my lower-privileged authenticated context with the owner's session context, I gained:
- Full account access
- Ability to modify account settings
- Ability to change phone numbers
- Ability to delete store
- Ability to change emails
- Full store control
The final exploit chain became:
Manager → Stored XSS → Owner Session Compromise → Privilege Escalation → Account Takeover
Lessons Learned
1. Self-XSS Findings Should Not Always Be Ignored
Sometimes the question is not:
"Can I execute JavaScript?"
The real question is:
"Who else can be forced to execute it?"
2. Role Testing Creates Impact
Many critical bugs exist between permission boundaries.
Always test:
- Owner vs Staff
- Admin vs Moderator
- Manager vs User
3. Workflows Matter More Than Individual Bugs
The vulnerability was not just XSS.
It was:
- Role design
- Workflow trust
- Missing output encoding
- Session exposure
The chain created the impact.
Conclusion
What started as a simple broken image payload eventually led to complete account takeover.
The biggest lesson from this finding:
Never stop at "it's just self-XSS."
Sometimes the highest impact vulnerabilities are hidden behind user roles and workflow assumptions.