Exploiting Bad Firebase
Recent Events
Recently, I found several vulnerabilities in a piece of software I use almost every day which granted me full access over critical infrastructure. This software acted as a pass monitoring service that did attendance, student services, and hall passes. The company itself provides this service to several different organizations that were all vulnerable to the same attack.
They set up their Firebase wrong. This, as you will come to learn, as a fairly common vulnerability which gives extreme degrees of control over an application.
Near the end, I found I could set the global quote of the day, change the appearance of the site, assign passes of any length to anyone, and scrape the sensitive data of their users.
Recon
Detecting Firebase is as easy as taking a deeper look with a tool like BurpSuite. It becomes immediately obvious through the WebSocket created that Firebase is in use. These websocket requests then provide interesting information about database routes and authentication.
I found that JSON objects were stored at specific endpoints and this is how informatiom was maintained throughout the entire service.
Also, the website did utilize an authorization key to make database requests. Specifically, it used Google’s auth to generate access and ID tokens (this will be important later).
How can we use this?
Well, Firebase conveniently provides a REST API that can be used to make database changes, provided that you have the proper authentication. Knowing this, I decided to fire off a PUT request to an endpoint designed for tracking school hall passes, and created my own 6 hour long pass. To my delight, it had worked. There was no validation for length of time, or the person, or anything else about the request.
While that is technically not bad Firebase, the next vulnerabilites are. With more scanning, I found that the database used a QOTD endpoint to recieve the quote of the day to display to every user on the platform. Naturally I fired off another PUT request to this endpoint, and to my horror, it let me change it! I, for the record, immediately reversed this change.
Some people in the know might be asking: how are we getting auth tokens? That is a good question. The token is only set to live for 3600 seconds once generated and the only way I knew how to generate a token was to intercept one with BurpSuite, or to look in browser local storage. This is where the refresh token comes in.
After prodding around the JS and finding their Firebase API key, I was able to make a POST request to securetoken.googleapis.com/v1/token?key=THEIR API KEY, with my refresh token. A refresh token, for those unaware, does last forever. With this, exploitation became very easy. I was able to pretty much read whatever data I wanted, and I could have likely destroyed or defaced the service.
Preventing Attacks
Fun fact: I’ve actually never used Firebase for my own projects before. I pretty much scrapped together all the knowledge I needed for exploiting this on the fly and it worked out. However what I do know is possible is deeper authentication on specific endpoints. This could easily be fixed by creating some sort of administrator token to be used for most of the endpoints.
For the “changing values of your own passes” deal, some verification of the values being sent to the backend would mitigate further attacks.
Reporting
I reported all of this immediately to the company in question.