8/25/2021
The web is full of user reviewed rating websites that we trust with our lives every day. Glassdoor allows us to see inside a company; Amazon reviews allow us to see what it is like to own a product; Yelp for restaurants... this is just the world that we live in.
But, what if you could sway the rating system? On Yelp, you could make a restaurant appear at the top of every search! Like in a dream, everyone would flock to your restaurant. Or, you could kill a competitors business, making yours look more appealing. This would be an amazing weapon to gain a competitive advantage on the rest of the market. In this article, we discuss a business logic vulnerability that was able to skew the ratings systems on a popular location-based ratings site.
The company asked to remain anonymous and to have no screenshots of the bug. So, we will get creative! To demo the bug, we will look at Juice Shop; the bug from OWASP Juice Shop is essentially the same as the real site. For those not familiar, OWASP Juice Shop is an intentionally vulnerable site from the Open Web Application Security Project (OWASP). In fact, this was one of my main resources for learning prior to becoming a security engineer at my current company.
OWASP Juice Shop has a customer feedback functionality, which is normal for many applications. This ratings system is on a scale of 1-5 where a sliding scale can be set to choose the rating. On the backend request, this is simply an integer being sent. What if we changed this to something that is NOT 1,2,3,4 or 5? The request for the customer feedback is shown in Figure 1 below within Burp.
By changing the rating to a non-expected value, such as -100 shown in Figure 1, we can drastically affect the overall customer ratings! This works in either the positive or negative direction. The challenge for this is titled give a devastating zero-star feedback to the store. On Juice Shop, we can change the rating value to be set to 0 in order to solve this challenge. Now, this website is meant to be vulnerable. Does this bug look the same on a real and in production website?
The target website stores information about a location and allows for ratings this specific type of location. When giving a rating on the user interface, the options are given as a collection of 5 stars. The user highlights the amount of stars for the rating (1-5) and this is the value sent to the backend. As a result, it is not possible to enter a value other than 1-5 in the UI. As demonstrated in the example above, this is not enough though! Client-side restrictions are a futile security protection.
This seemed like fertile testing ground to go through, as I remembered the Juice Shop example from years ago. I used a web app pentesters best friend Burp to proxy the request and altered the rating to be -5000. But, this failed with a 500
error, which surprised me, since the application had never thrown me a 500
error like this before. After trying increasingly smaller negative numbers, to my surprise, -500 worked! I did the same thing in the positive direction with positive 500 and this worked as well. It appears they had some sanity checking on the values but not enough. What does this actually mean though?
Most rating systems are calculated by taking the average. This average is then used everywhere on the website for finding locations to visit. In fact, this overall rating is the most important descriptor about a location to decide if people do or do not go somewhere. Being able to inject a rating of -500 or +500 would drastically raise the average rating (even past 5 stars) or drop the rating of the location significantly. Raising it could make the location extremely popular while dropping it would make the location unlikely to be visited.
In a community that relies upon the reviews of others, being able to have this large of a stake in the voting on each location allows for the rise in popularity or the downfall of a place by a single person. This compromises the people sourced system entirely; eventually, this could break the trust of the users and force them to use other services. Luckily, the fix for the bug is simple: only allow values from 1-5 on the backend.
From previous experiences, I am nervous when trying to report security vulnerabilities. As a result, I have learned to be very kind and come from the perspective of "I found this bad bug. Please let me help you fix it." If you go in guns blazing and attacking the service team with comments about how crappy the software is and how great of a hacker you are, then you are unlikely to have a good response with the team (we've all made this mistake before). Keep this in mind when reporting to companies or people without a formal bug disclosure program especially. Yes, I know testing on these sites is technically illegal; I hope that people see the good in us though, as the testing is done in good faith. In this particular case, the company had the best response I have ever received!
My initial communication with the company was to a senior engineer over LinkedIn. The company did not have a security email so this was my best course of action. Eventually, a support ticket from the support@company.com
got back to me as well but hours after the initial contact with the engineer on LinkedIn.
Since the initial LinkedIn message only allows for only 300 characters, after the initial connection I sent a longer message explaining the details of the bug with a few screenshots. In particular, I sent a screenshot with the overall rating for the location being 0 stars and the next one being 9 stars, even though the limit is 5 stars. At this point, the engineer replied Oh wow, that's pretty bad. we are on it. " The engineering team fixed the bug immediately.
After this, the CTO of the company added me on LinkedIn and thanked me for the finding and responsible disclosure. The CTO let me know that a security engineering position would be opening up soon; they wanted me on the short list for the job once the position opened up. Additionally, they offered me a lifetime membership to the application! Considering I use the application quite a lot, this was very exciting for me :) A huge shoutout to the engineer and CTO for the amazing response to the finding. This makes me happy to find bugs and report them to make the internet a safer place.
Vulnerabilities are not always complicated injection attacks. Commonly, they are centered around how the logic of the site; these bugs are undetectable by scanners. Although throwing <script>alert(1)</script>
may find some XSS, lots of bugs require an understanding of the applications logic and expected functionality. Prior to throwing random inputs everywhere, ensure that you understanding the business-logic of the application in test.
Feel free to reach out to me (contact information is in the footer) if you have any questions or comments about this article. Cheers from Maxwell "ꓘ"Dulin.