HIGH password sprayingfirestore

Password Spraying in Firestore

How Password Spraying Manifests in Firestore

Password spraying against Firestore-backed applications exploits a common misconfiguration: trusting client-side authentication without enforcing server-side validation. Unlike SQL injection, which targets query syntax, password spraying in Firestore targets the application's authentication layer before database access. The attack pattern involves using a small list of common passwords (e.g., "Password123", "admin") against many user accounts to avoid lockout thresholds.

In Firestore applications, this manifests through the client SDKs (web, Android, iOS). A vulnerable app might initialize Firestore with credentials obtained from a separate login endpoint, then query protected collections. The critical flaw is that Firestore Security Rules may incorrectly assume authentication has already been validated elsewhere, or they may lack proper request.auth checks.

For example, consider a web app that uses Firebase Authentication but has overly permissive rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if true; // VULNERABLE
    }
  }
}

An attacker who guesses a user's password via the authentication endpoint (e.g., https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword) receives an ID token. They then use that token in the Firestore client SDK to read any document. The attack succeeds because the rules allow unauthenticated or improperly scoped access.

Another variant occurs when apps use custom tokens without validating token claims. If the app's backend issues tokens with excessive privileges (e.g., admin: true) based on weak password checks, an attacker with a guessed password inherits those privileges in Firestore.

The Firestore-specific risk is that a single successful guess grants direct document access, bypassing any application-layer authorization. Unlike relational databases where row-level security might limit exposure, Firestore rules are the primary gatekeeper. Misconfigured rules combined with weak passwords create a catastrophic data exposure path.

Firestore-Specific Detection

Detecting password spraying vulnerabilities in Firestore requires testing both the authentication mechanism and the Firestore Security Rules. middleBrick's black-box scanning approach tests the unauthenticated attack surface by attempting to interact with Firestore endpoints with weak or no credentials.

The scanner performs two key tests:

  • Unauthenticated Endpoint Discovery: It probes common Firebase project endpoints (e.g., firestore.googleapis.com/v1/projects/.../databases/(default)/documents) to see if any collections are publicly readable. This identifies rules like allow read: if true;.
  • Authentication Bypass via Weak Credentials: Using a list of common passwords, the scanner attempts to authenticate against the Firebase Authentication REST API (identitytoolkit.googleapis.com). If a weak password succeeds, it then uses the returned ID token to query Firestore documents that should be protected. A successful read indicates a broken authentication + authorization chain.

For example, a scan might reveal a finding like:

SeverityCategoryFinding
HighAuthenticationFirestore rules allow read access with a valid ID token from a weakly authenticated user. Password "Password123" succeeded for user "john@example.com".

middleBrick's OpenAPI/Swagger analysis also helps: if the API spec documents Firestore-backed endpoints (e.g., /api/users/me returning user documents), the scanner correlates runtime findings with the spec to map vulnerable paths.

To manually verify, use the Firebase CLI or curl:

# Attempt authentication with a weak password
curl -X POST \
  'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=[API_KEY]' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "target@example.com",
    "password": "Password123",
    "returnSecureToken": true
  }'

# If successful, use the idToken to read Firestore
curl -H "Authorization: Bearer [ID_TOKEN]" \
  'https://firestore.googleapis.com/v1/projects/[PROJECT_ID]/databases/(default)/documents/users/target@example.com'

If the second request returns user data, the application is vulnerable to password spraying leading to data exposure.

Firestore-Specific Remediation

Remediation requires hardening both authentication and Firestore Security Rules. Never rely on client-side checks.

1. Enforce Strong Password Policies
Use Firebase Authentication's built-in password strength requirements. In the Firebase console, set minimum password length (≥12 characters) and disallow common passwords. Programmatically, enforce during sign-up:

// Example using Firebase Admin SDK to validate password strength
const admin = require('firebase-admin');

function validatePassword(password) {
  const minLength = 12;
  const hasUpper = /[A-Z]/.test(password);
  const hasLower = /[a-z]/.test(password);
  const hasNumber = /\d/.test(password);
  const hasSpecial = /[!@#$%^&*]/.test(password);
  
  if (password.length < minLength || !hasUpper || !hasLower || !hasNumber || !hasSpecial) {
    throw new Error('Password does not meet complexity requirements');
  }
}

// Call this before creating a user with admin.createUser()

2. Implement Account Lockout or Rate Limiting
Firebase Authentication does not natively support lockout. Implement it at the application layer using a cache (e.g., Redis) to track failed attempts per IP/email. Alternatively, use App Check to restrict authentication requests to your genuine apps.

3. Harden Firestore Security Rules
Rules must validate request.auth and ensure the user can only access their own data unless explicitly privileged. Example rule for a users collection:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Users can read/write their own document
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
    
    // Admin collection requires custom claim
    match /admin/{document=**} {
      allow read, write: if request.auth != null && request.auth.token.admin == true;
    }
  }
}

Use request.auth.token to check custom claims set by your backend. Never use request.time or request.ip for authorization—they're easily spoofed.

4. Monitor and Alert
Enable Firebase Authentication logging and set up alerts for suspicious patterns (e.g., multiple failed logins from one IP). Use middleBrick's Pro plan continuous monitoring to track Firestore rule changes and rescan after deployments.

5. Test Your Rules
Use the Firebase Emulator Suite to test rules locally with simulated auth tokens. Write integration tests that attempt unauthorized access.

Remember: Firestore Security Rules are the last line of defense. They must assume the authentication layer can be bypassed and validate every request's scope.

Why This Matters for Firestore Developers

Firestore's real-time, client-accessible architecture makes it uniquely susceptible to password spraying fallout. A single compromised credential can give an attacker persistent, low-and-slow access to live data via the client SDK, often without triggering traditional intrusion detection. Unlike server-rendered apps where each request hits your backend, Firestore clients talk directly to Google's servers. Your security rules are the only barrier.

The OWASP API Top 10's Broken Authentication (A02:2021) category explicitly covers credential stuffing and password spraying. In Firestore contexts, this flaw frequently maps to PCI-DSS requirement 8.2.4 (password complexity) and HIPAA §164.312(a)(1) (access control).

middleBrick's scanning specifically tests this attack chain: weak password → valid ID token → unauthorized Firestore read. The scanner's 12 parallel checks include Authentication and BOLA/IDOR, which directly assess whether a token with low privileges can access data it shouldn't.

Frequently Asked Questions

Can middleBrick scan Firestore databases that are not publicly accessible?
No. middleBrick performs black-box scanning without credentials. It can only test endpoints accessible from the public internet. For internal Firestore databases, use the CLI tool in your network or integrate the GitHub Action into your CI/CD pipeline to scan staging environments.
Does middleBrick fix my Firestore Security Rules automatically?
No. middleBrick detects and reports vulnerabilities with remediation guidance. It does not modify your configuration. You must update your Firestore rules manually based on the provided recommendations.