Disclaimer: I do not have permission to disclose the report, therefore I needed to heavily redact this writeup. Thank you and happy reading!
Stored cross-site scripting is a vulnerability where an application would store untrusted malicious code from users. The combination of being lethal whilst having a low attack complexity has placed XSS at number 7 of OWASP Top 10. In this writeup, I will be explaining to y’all readers how I was able to find a Stored XSS on one of the biggest E-commerce sites in Asia.
As we all know, most e-commerce websites allow sellers to add their own product descriptions on their product pages. Since this is one of the attack vector for Stored XSS, I decided to input the following XSS payloads for shallow testing;
- “ onclick=alert(1)//<button ‘ onclick=alert(1)//> */ alert(1)// — Polyglot Payload
- %7d%29%3b%7d%29%3balert%60xss%60;%3c%2f%73%63%72%69%70%74%3e — URL Encoded
- ‘“><a href=’www.anything.com’>Click Here</a> — HTML Injection Check
I would normally rely on the above XSS payloads to check for possible reflection since it is basically impossible to check using all of the payload available out there. After inputting the payloads, I would then check for HTML injection first, meaning executed HTML tags. If the web application executes HTML tags, there is a good chance that it can be leveraged to an XSS. In this case, I was fortunate enough that the web application is executing some of my HTML tags. Sadly, it is not executing my script tags.
After a couple of hours tempering the endpoint with XSS payloads, I reached the following conclusion:
- The web application is implementing WAF (Web Application Firewall)
- The product description uses Markdown to parse the user’s input
For those of you who don’t know what Markdown is, it is a lightweight markup language that you can use to add formatting elements to plaintext text documents. Since Markdown offers high customizability for users, misconfiguration often happens. I decided to spend the next hour searching for possible payloads that would allow me to bypass the above conditions. After reading multiple blog posts, I found out that one of the most common bypasses is using Unicode encoding, therefore I tried to input the following payload:
Fortunately, the web application decodes the Unicode to plaintext and execute the payload when the anchor tag is clicked. Due to the impact and placement of the bug, I submitted this issue as a high severity issue. Thankfully, the security team agrees and rewarded me with a total of $400 after 2 months of waiting.
Drop a clap and comment if you want me to do another write-up. Thank you for your time and have a nice day!