$6000 Reward. How I did a Global Stored XSS via Reflected Log Cache Poisoning on Starbucks

Erick Fernando
4 min readJun 3, 2024

--

Hello Guys,

In this article, I will demonstrate how it was possible to execute a stored XSS attack through reflected log poisoning on Starbucks’ websites, resulting in the highest reward paid by the bug bounty program.

How did I notice and explore the potential attack?

One day I was fuzzing for XSS using Nuclei within some scopes via Path like this:

{{BaseURL}}/%27%22></script><script>alert(‘erickfernandox’)</script>

In parallel, I was using another template in Nuclei to conduct fuzzing in a different manner. With it, I was searching for JavaScript functions in the page’s code that reflected certain parameters in a clusterbomb format, using the following structure:

{{BaseURL}}?{{param_fuzzing}}=erickfernandox

The goal was to find the value “erickfernandox” reflected within parentheses (‘erickfernandox’) to analyze potential DOM XSS vulnerabilities within JavaScript functions.

The Nuclei result indicated that there was a parameter reflecting on the Starbucks website using a URL like the one presented below, and I accessed it:

https://starbucks.ca/account/x?id=erickfernandox

Upon opening, surprisingly, I confirmed the presence of an XSS payload from the other template.

In the HTML of the page, the payload was in the following structure:


</script>
...
{"location":{"pathname":"/account/signout/'"></script><script>alert(‘erickfernandox’)</script>
...
</script>

However, accessing the link with XSS payload directly in the browser did not work; the company’s WAF blocked it.

URL: https://www.starbucks.ca/account/signout/%27%22></script><script>alert('erickfernandox')</script>

So it didn’t make any sense at all.

When refreshing the page, sometimes the XSS would reflect and sometimes it wouldn’t, because there was a rotation of URLs within the:{“location”:{“pathname”:”URL_PATH”}

I kept hitting F5 and saw that the page kept changing links in the HTML that other users accessed, but it only ever showed a maximum of 3 different URLs.


{"location":{“pathname":"-assets/lodash.0d7e56ea0a691ecd5997.js" ...

{"location":{"pathname":"/menu" ...

{"location":{"pathname":"/'"></script><script>alert('erickfernandox')</script> ...

So, I thought it was a cache poisoning issue that was storing URLs in the cache and showing them to other users.

However, after analysis, it was possible to see that the system wasn’t storing anything in the cache:

So, it started to make even less sense!!!!!!

After a while, my XSS payload disappeared from the HTML and different links started to appear.

I assumed they were access links from other users, because my template had already injected that, so I thought about sending multiple requests to the site to see if/when that would reflect.

I wrote the following bash code and ran it in a loop on 15 VPS in 2 different countries:


for (( c=1; c<=10000; c++ ))
do
echo "https://www.starbucks.ca/account/%27%22><erickfernandox>"|httpx
done

I analyzed the HTML of the page from time to time. After an hour of sending requests, the following payload started appearing in the page’s source code:


<script>

{"location":{"pathname":"/account/'"><erickfernandox>"}

</script>

So I proved my thesis that was being reflected from URLs accessed by users. Therefore, I concluded that this was a log poisoning in a cache memory that was being reflected in the page’s HTML every hour.

I made these requests in a loop for 24 hours, and during the 24 hours, all the URLs reflected in the HTML of the Starbucks sites included my above payload. This proved that it was possible to maintain this attack persistently.

Technology and Operation Process of the Attack

Trying to understand which technology was behind this JSON structure, I saw that it was a React application using React Router to handle the website’s routes.

However, somehow it was fetching routes from accessed URLs stored in cache. I put together a diagram to show how this process of sending the malicious payload, caching, and reflecting it on the page worked in theory:

In this it was seen that this flaw not only worked on a specific website but could be reproduced on all company websites: www.starbucks.*

Finally, the company managed to reproduce the flaw, changing it from High to Critical and paying the highest reward value of the Bug Bounty program.

Thanks for reading! And good bounties.

#bugbounty #hackerone #xss

--

--