[00.00_r1gor]
[00.00_bugbounty]
r1gor

all write-ups

Broken Firestore Rules Leaked Every Company's Hiring Strategy

Target is an AI-powered recruiting platform. Companies use it to search candidates, define custom evaluation criteria, and let AI score matches. Free tier gives 5 credits. Enterprise plans cost thousands per year.

The platform uses Firebase/Firestore as its primary database. The Firestore security rules on two collections were too permissive.

the bug

Create a free account. No email verification needed. Get a Firebase ID token. Query the Firestore REST API:

# sign up (any email, no verification)
curl -s "https://identitytoolkit.googleapis.com/v1/accounts:signUp\
?key=$APIKEY" \
  -d '{"email":"anything@whatever.com","password":"Test123!",
  "returnSecureToken":true}'

# download all search results from all organizations
curl -s "https://firestore.googleapis.com/v1/projects/[PROJECT]/\
databases/(default)/documents/search_results?pageSize=300" \
  -H "Authorization: Bearer $TOKEN"

It returned everything. I paginated through 30 pages of 300 documents each and it was still going. 9,000+ records sampled, true total likely much higher.

The rerank_jobs collection was the same. 6,000+ documents with ownerOrgId and ownerId for every search job. I enumerated 2,566 unique organizations and 3,173 unique users.

what was exposed

Each search_results document contained the searching organization's proprietary AI evaluation. Example from another company's search (redacted):

Criteria: "Storage" - "The candidate has experience in the
           storage domain."
AI Result: yes
AI Reasoning: "Candidate worked with CosmosDB, PostgreSQL,
  Azure data services and built data pipelines, indicating
  storage domain experience."

Criteria: "ICT" - "The candidate has experience in the ICT
           industry."
AI Result: yes
AI Reasoning: "Roles at IBM, Accenture, Microsoft and other
  tech firms demonstrate clear ICT industry experience."

Match Rate: 100%
AI Provider: fireworks

This tells you exactly what role that company is filling, what skills they value, and how they evaluate people. That is their internal hiring strategy, visible to anyone with a free account.

The exposed fields per search result: - autopilot.responses[].criteriaTitle - custom evaluation criteria - autopilot.responses[].criteriaText - detailed rubric text - autopilot.responses[].resultExplanation - AI reasoning about candidate fit - autopilot.matchRate - match score 0-100 - searchId - links to search config - Candidate profile data (name, title, LinkedIn) - public by design, that is the product

credit system bypass

Free accounts get 5 credits. Enterprise customers pay for unlimited access. Through the Firestore REST API, a free account can download unlimited search results that paying customers generated. The entire monetization model bypassed.

what was properly secured

These collections all returned PERMISSION_DENIED correctly:

users, orgs, projects, sourcing_contacts, contacts, agentic_projects, agent_leads, invites, activities, export_jobs, integrations, tags

So the issue was specific to search_results and rerank_jobs. Not a blanket misconfiguration.

root cause

The Firestore security rule was probably:

allow read: if request.auth != null;

Instead of:

allow read: if request.auth != null
  && resource.data.ownerOrgId == getUserOrgId(request.auth.uid);

Any authenticated user can read any document. The fix needs org-scoped read rules. Complication: search_results documents do not have ownerOrgId yet, so that field needs to be backfilled from the linked rerank_jobs document.

Also, Firebase signUp creates fully functional accounts with any email including @[company].ai and @[company].work. No verification. An attacker can spin up throwaway accounts endlessly.

scale

  • 9,000+ search results sampled, pagination still going
  • 2,566 customer organizations
  • 3,173 users with Firebase UIDs
  • Zero cost: free account, no email verification, no credits consumed
  • Competitive intelligence for thousands of companies' hiring strategies

The candidate data (names, job titles) is public. That is the product. But the AI evaluation criteria, scoring rubrics, match reasoning, and search configs are proprietary to each organization. That is the breach.