How a Promotional QR Code Exposed Production PII
What started as a completely ordinary visit to Mouzy, a fusion drink outlet, turned into an unexpected security assessment. After paying, the cashier handed us a small card with a QR code and told us we could play a game called Zuzy Run to win rewards. Most people would scan the QR code, play the game, and move on. I scanned it and had a different thought: “I wonder how secure this is.”
That thought kicked off an unexpected security assessment that eventually led to the discovery of a critical Firebase misconfiguration exposing sensitive production data.
The Target & Recon
The QR code redirected to
https://zuzyrun.gamefaktory.com/?token=.... The application was a browser-based game where
players used limited “hearts” (lives) to
play and accumulate points for rewards. At first
glance, it looked like a typical promotional game.
But while interacting with it, the client-side logic
customarily felt unusually heavy and session state
appeared to be stored entirely locally. That usually
means one thing: interesting things may be happening
in the frontend.
I started with standard passive recon checking DevTools, inspecting the network requests, and reviewing local storage layouts. The frontend bundle immediately exposed a standard Firebase configuration object:
An exposed Firebase API key alone is not automatically a vulnerability; client configs are public by design. The real question is whether backend security rules are correctly configured. That became the core focus.
Firestore Enumeration
From the JavaScript bundle, I identified the Firebase project and targeted Firestore’s REST API. Firestore document paths follow a predictable layout:
https://firestore.googleapis.com/v1/projects/PROJECT_ID/databases/(default)/documents/COLLECTION
I began testing likely collection names referenced in the frontend. That’s when things got serious.
Critical Findings
Unrestricted Player Data Access
The following endpoint returned data without requiring any authentication checks:
GET /v1/projects/[REDACTED]/databases/(default)/documents/players?pageSize=100
This completely exposed player records containing names, phone numbers, scores, and gameplay metadata. Because this is PII, unauthorized users could essentially enumerate the entire active player database directly from Firestore.
Gameplay Token Exposure
Another collection endpoint was completely readable:
GET /v1/projects/[REDACTED]/databases/(default)/documents/tokens?pageSize=300
This exposed active gameplay tokens tied to active QR sessions controlling game lives. Obtaining valid tokens allowed session reuse, letting an attacker hijack active sessions and abuse reward distributions.
Admin Collection Exposure
The most critical exposure layout leaked complete administrator details:
GET /v1/projects/[REDACTED]/databases/(default)/documents/admins
This exposed administrator records containing admin names and associated Gmail addresses. While passwords weren't directly leaked, mapping out admin identities significantly spikes the attack surface for targeted social engineering and phishing.
Impact & Disclosures
The Firestore rules effectively allowed unauthenticated read access across sensitive backend buckets. An attacker with basic structural knowledge could harvest player records, enumerate admin accounts, and capture active session keys.
Severity Assessment: CRITICAL
I stopped testing immediately after confirming the scope without dumping database assets, saving target logs, or running destructive tests. I drafted a disclosure report summarizing the flaw and contacted the vendor. To their credit, the response from GameFaktory was extremely fast and professional. They acknowledged the issue, accepted responsibility, and mitigated the rule paths quickly. That is exactly how responsible disclosure should work.Lessons Learned
Public configs aren't flaws: Don't panic because your frontend maps an API key. The issue is entirely dependent on backend access rules.
Frontend code leaks architecture: Even heavily minified source code maps database collections, routing variables, and business endpoints. Defenders need to verify these paths before attackers do.
Promotional scopes require protection: This wasn't a financial platform; it was a basic promotional loop running on a fusion drink outlets. Yet, it handled live user logs, identity records, and admin data. If it touches variables, lock it down.