
[Music] Okay. Hi everyone. Um, so yeah, today I'm going to be talking about exploiting Firebase apps with a tool I wrote called BaseRunner. First, a little bit about me. I'm a senior cyber security consultant at IOSRo, but I started my career at MWR. So, some of you may recognize me from there. At uh IOSRo, we do security consulting mostly for startups mostly in the fintech and crypto spaces. Um we do a lot of smart contract auditing on the EVM blockchain, but also a fair amount of web and cloud pentesting. And I like to split my time between all these things so I don't get bored. So our story begins with a pentest on a Firebase app. Um of course. So, I was
taking a look at this and I was using Burp to intercept the requests, you know, as one does on a pentest and I noticed requests that looked an awful lot like database queries. So, as one does, I thought, can I change these database queries? Can I make them do things that the app shouldn't allow? Like maybe changing other users or, you know, changing stuff about my own user account I shouldn't be able to. And I was able to do that successful, but it was really irritating to do in Burp Suite. And I I'll show you what I mean on the next slide. So, uh here we have one database query to like read from a
table. Uh we've got three different requests. The actual query is in the first request. You see it's nice and readable with all that URL encoding. Um and then the result of the query you only get in like the third request. So this was really annoying to do and I thought to myself, well if the client if the front end is making these requests then surely there's like a nicer way to do this. So I started reading up a bit about Firebase. Uh so yeah, what is Firebase? Why do developers love it so much? Well, it's a serverless application platform. Uh it's really quick and easy to set up. You go on GCP, you click a few buttons, bam,
you've got a Firebase app. Um, it handles authentication for you. So, you've got login, user registration, passwords, phone numbers, all that kind of stuff, social registration, MFA, what everything you want. And you've got data persistence. So, with a few clicks, you can really have a whole generic backend for your web application, whatever it may be. And what that means is you can build your whole application in front-end JavaScript. H you can build your whole application in front-end JavaScript. So traditionally we have a browser that speaks to an application server that speaks to a database. Firebase the browser speaks directly to the database. Um so there are a few different database options we have. The first and most
common one is cloud fire store which is kind of like MongoDB with your collections and documents and JSON uh but like not as featured. Uh there's also real-time database which is just a massive JSON object that you put all your data in. And then they've also recently added Postgress but I haven't looked into that. So uh task for someone in the audience maybe. Uh you also have bucket storage which I don't have a funny picture for. Uh so the whole key to this is this Firebase config. Uh the way that a Firebase application communicates with its database and with the authentication and with the buckets and everything like that is through this config which is a
piece of JSON information with like API keys and URLs and stuff. And you will find this JSON object on any Firebase app in the JavaScript in the front end or if it's a mobile app it'll be in there. Um, if you have this piece of code, then you can impersonate the application to the backend APIs. And that's exactly what BRERunner does. So, you start out by copying your JSON object, putting it in that uh Firebase config box over there. Then you can uh log in with an application user account. You don't have to do this part, but you can. Uh, you can use email, password, or your phone number or even Google login. Google login was contributed by a
thirdparty guy named Adicha Saligramma. So, thanks to him. Um, and then once you've done that, you can make a bunch of database queries uh that I've created helpful JavaScript templates for on the side using either cloud fire store or real-time database or I also recently added support for bucket storage and yeah, the tools available on GitHub. So, the kinds of things you might want to do here is maybe you want to read the credit cards table. Maybe you want to modify your users so that you're a super admin. Maybe you want to give yourself like a million round voucher. Maybe you want to delete someone else's order so they don't get it. You know, the
possibilities are endless. Um, but at this point, you're probably asking like that that can't be right. This can't be how it's supposed to work, is it? Surely not. And no, technically not. So the control that Firebase gives us to prevent these kinds of issues are these things called fire store rules. Real-time database has a similar concept, but I'm not going to cover that because of time. Uh but it's basically the same idea. So you have this funky DSL where basically you match uh some path which can be one or more collections and you allow different actions based on different conditions. Um, so the default rule when Firebase first came out in 2016 in beta was uh
match all collections and allow everything. So this would be like I have your JSON object, I can do anything on your database. Uh, this was obviously horribly insecure. So they changed it later to require authentication which just means that like I can register a user account and then have control over your whole database. So not not a big improvement. Uh but of course the idea is that you're supposed to be a conscientious developer. You're not supposed to use these defaults. You're supposed to write your own rules. So maybe you would write a rule like this matching your users database to say like we could read users if we're logged in and we can update a user if we're logged
in and we are that user and also we don't change the name. And you can do very sophisticated things here with like looking at different collections and looking at the request and data validation and all that kind of stuff. Um, but the problem comes in when you want to get more granular than that. So let's say we have a user document here with a name, email address, and phone number. We're happy for the name to be public. The email address and phone number, we don't want that to be public. But all Firebase lets us do is allow read or deny read. Like we can't prevent, you know, the whole thing from being read. So what we have to actually do to get
around that is we have to just restructure our whole database around our access control rules. We would have this user and then every user would have to have a private subolction with a document that has their private fields in it. And then we would write a rule kind of like this to uh to enforce that validation. And already this nesting is looking a bit hairy with a very simple example. So you can imagine if you have a user table with like 15 different fields, it's going to get messy very quickly, especially if you have lots of different orth rules that you want to apply. Um so that's one problem with rule. A few other problems with rules
are they're very different from how we normally think about how web apps interact with databases. Like you're basically with Firebase, you're basically giving every user of your application a login to your database and you have to like thread model around that and you have to think of everything that can go wrong and either like write a rule or structure a database to prevent that problem from happening. And then this is also separate from the rest of your code. The rules are in this funky DSL. They live in the Firebase admin. They're not with the rest of your code on GitHub. So the best rule you can set is denial, which is kind of the opposite of that
initial default. Match everything. Don't allow read or write at all. Um, but then you might be asking, well, how will our application actually work if we're just locking the database like that? And the answer is the Firebase admin SDK. So this is a serverside NodeJS library. It requires a service account private key to work and it bypasses all security rules. So if we have denial set, we can still access our database with this admin SDK. Uh it also can't be used in a browser. So that means we are not so serverless after all. We're going to need an application server. But if you really like Firebase, you can use a cloud function instead. You just have to
upgrade from the free plan. So I don't think Google or Firebase will ever like totally acknowledge the issues with these things, but they have made the defaults like a little bit better these days. So by default in 2025, if you create a new Firebase like fire store database and you just click through, it'll start in production mode, it'll deny all. If you explicitly say certain test mode, it'll have a temporary allow all uh with a nice warning telling you about everything I've just said. Uh unfortunately, not everyone enables that. So, as I was preparing these slides, uh or finishing these slides up last night, there was a massive hack of the Firebase database that was badly secured. Millions of
documents compromised for, you know, exactly this reason. So developers are not using these secure defaults. Um so what we can conclude is that the best practice for Firebase architecture is a browser that talks to an application server that talks to a database. Maybe use some cloud functions if you really want. Uh yeah, thanks everyone. We are.com. Uh, you can get the tool on GitHub and if you'd like to get in touch with me, I have my website and then my email address and then my account on Zitter. Thanks. Yeah. Any questions?