Bestiefy — IDOR Galore
Bestiefy
Bestiefy is a web app where users create short 10 question quizzes with questions about themselves, these can be shared easily with a short url like this https://bestiefy.com/q?=abc12.
Results to a quiz are stored in a leaderboard that anyone can view, but only the quiz creator can see the exact answers provided by answerers
.
Discovery
So I saw a few people posting these links on their Snapchat stories to this new web app, and as with any new website I find, I look around for some low hanging fruit. Just looking through the source code and network connections, the first thing I noticed was, when taking a quiz, clicking an answer automatically shows you if it’s correct or not, without making any network requests, this means that all the answers must be stored in the browser. This led me to look at the /api/quizzes
endpoint…
Vulnerability
After looking around at what requests are made to the API, the first thing I noticed was there’s no session, csrf or auth tokens being sent across (apart from a creator ID, which doesn’t matter much, as you’ll see), so anyone could just play around with it. Which is what I did…
Exploits
There are a few exploits possible with this as a result of the endpoint being completely open to anyone. Here are the ones I could think of.
Get all answers to a quiz
The first example I can think of is the first issue I found when the answers to questions must have been stored in the browser before being submitted, so I found the endpoint related to this. The following request will return all questions and their answers (and other info) of the quiz in JSON format:
GET https://bestiebackend.herokuapp.com/api/quizzes/{quid_id}
Add custom leaderboard entry
The endpoint for submitting quiz results is also unprotected, so arbitrary entries can be input into the leaderboard, bypassing the web page filters. This can be done with the following request:
PATCH https://bestiebackend.herokuapp.com/api/quizzes/{quid_id}
{
"answerers": {
"uid": str,
"name": str,
"score": int
}
}
The value supplied for uid
doesn’t matter at all, can be a random string. The name
value can also be anything, it bypasses the 15 character limit on the web page. The score
field can be any integer value, even above 10…
Completely replace quiz
The worst one I could think of is completely replacing the contents of a quiz. I tried doing this by repeating the same request used to make a quiz and tweaking the qid
and the creator_id
values but no luck. After a little while of looking around I noticed you can delete your own quiz, so I checked, and yes of course there’s an IDOR. So you can delete any quiz with the following request:
DELETE /api/quizzes/{quiz_id}
Now, to replace a quiz. I remembered when I was playing around with replacing quizzes using the API endpoint to create a quiz, that I couldn’t actually replace an existing one, but I could specify any other quiz id and it would work. So you can then chain these two together to completely replace a quiz’s contents by first deleting it and then creating one with the same id using this request:
POST /api/quizzes
{
"qid": "{quiz_id}",
"name": "quiz name",
"questions": [
{
"question": "question",
"options": [
"answer0",
"answer1"
],
"color": 0,
"answer": 0
}
...
],
"langloc": "EU-EN",
"creator": "whatever"
}
Fix
After I emailed the developers a couple of times, getting no response, I checked the website once more before sending another email, and I noticed an access denied error when trying to make a request to the API. This is due to a new Authorization: Bearer {token}
header. So i had a quick look to see what code was creating that token
So this must all be done on the client side, so I just needed to find how the j
variable was initialized so maybe I can recreate it.
I found a j.a.initializeApp()
with an API key and all other informaiton needed to create your own token. This then can be done with a simple POST request to:
https://identitytoolkit.googleapis.com/v1/accounts:signUp?key={api_key}
And the returned idToken
can then be put in the Authorization
header.
Extra stuff
As I did with my Netflix Party exploit, I created a little python script to automate all these hacks just as a fun little project:
https://github.com/kr-b/bestiefy_exploit
Disclaimer
I have tried to reach out to the developers, telling them about this vulnerability and possible fix ideas, but got no response.. So I’m just posting it for everyone to play around with.