Firebase Authentication Fundamentals
Firebase Authentication provides a complete identity solution with support for email/password, phone, OAuth providers (Google, Apple, GitHub, etc.), and anonymous authentication. While Firebase handles the complexity of token management and session handling, developers must still configure and use it securely.
Common Authentication Vulnerabilities
1. Unrestricted Email/Password Sign-Up
By default, anyone can create an account in your Firebase project. If your application is invite-only or has restricted access, you need additional controls:
// Server-side: Disable sign-ups via Firebase Admin SDK
// or restrict in Firebase Console under Authentication > Settings
// Client-side: After sign-up, check if the user is authorized
const userCredential = await signInWithEmailAndPassword(auth, email, password);
const token = await userCredential.user.getIdTokenResult();
if (!token.claims.approved) {
await signOut(auth);
throw new Error('Account not approved');
}
2. Missing Email Verification
Accounts created with email/password are not verified by default. Unverified accounts can be used to access your application if your security rules do not check verification status:
// Firestore rule checking email verification
match /protected/{docId} {
allow read, write: if request.auth != null
&& request.auth.token.email_verified == true;
}
Always send verification emails and enforce the check:
import { sendEmailVerification } from 'firebase/auth';
// After sign-up
await sendEmailVerification(userCredential.user);
3. Weak Password Requirements
Firebase defaults allow passwords as short as 6 characters. Enforce stronger passwords in your client code:
function validatePassword(password: string): boolean {
if (password.length < 12) return false;
if (!/[A-Z]/.test(password)) return false;
if (!/[a-z]/.test(password)) return false;
if (!/[0-9]/.test(password)) return false;
return true;
}
Note: Client-side validation can be bypassed. For truly enforced password policies, use Firebase's password policy configuration in the console or via the Admin SDK.
OAuth Security
Restrict OAuth Providers
Only enable the OAuth providers you actually use. Each enabled provider is an attack surface. Disable unused providers in the Firebase Console under Authentication > Sign-in method.
Validate OAuth Redirect URIs
Firebase allows configuring authorized redirect URIs. Restrict these to your actual domains:
- Your production domain (e.g.,
https://yourapp.com) - Your staging domain (if applicable)
localhostfor development only
Remove any wildcards or unused redirect URIs.
Link Account Hijacking
When a user signs in with an OAuth provider and the email matches an existing email/password account, Firebase may link these accounts depending on your configuration. An attacker who knows a user's email could potentially take over their account by authenticating through a different provider.
Mitigation: In Firebase Console, set "Multiple accounts per email address" settings carefully. The safest option is "Prevent creation of multiple accounts with the same email address" combined with email verification enforcement.
Token Security
ID Token Validation on the Server
When using Firebase tokens for server-side authentication, always verify them:
import { getAuth } from 'firebase-admin/auth';
async function verifyToken(idToken: string) {
try {
const decodedToken = await getAuth().verifyIdToken(idToken);
return decodedToken;
} catch (error) {
throw new Error('Invalid token');
}
}
Never decode the JWT manually and trust the claims without verification.
Token Revocation
Firebase ID tokens are valid for 1 hour by default and cannot be revoked individually. If you need to revoke access immediately (e.g., when banning a user), use session cookie-based authentication or check a revocation flag in your database.
// Revoke all refresh tokens for a user
await getAuth().revokeRefreshTokens(userId);
// In security rules, check the auth time
allow read: if request.auth.token.auth_time > resource.data.lastRevocationTime;
Custom Claims Best Practices
Custom claims are powerful but must be used carefully:
// Set custom claims (server-side only)
await getAuth().setCustomUserClaims(userId, {
role: 'admin',
organizationId: 'org_123',
});
Rules for custom claims:
- Never set claims based on unverified client input
- Keep the claims payload small (under 1000 bytes total)
- Claims are cached in the ID token, so changes take effect after the next token refresh
- Use claims for access control, not for storing user data
Rate Limiting and Abuse Prevention
Firebase Authentication has built-in rate limiting, but you should add your own application-level protections:
// Track failed login attempts
async function trackLoginAttempt(email: string, success: boolean) {
const ref = db.collection('login_attempts').doc(email);
if (success) {
await ref.delete();
} else {
await ref.set({
count: FieldValue.increment(1),
lastAttempt: FieldValue.serverTimestamp(),
}, { merge: true });
}
}
Consider enabling Firebase App Check to ensure requests come from your legitimate app instances and not from scripts or cloned apps.
Anonymous Authentication Risks
Anonymous auth creates temporary accounts that are easy to abuse. If you use anonymous auth:
- Limit what anonymous users can access in your security rules
- Set up account cleanup for abandoned anonymous accounts
- Rate limit anonymous account creation
// Firestore rule: Limit anonymous users
allow read: if request.auth != null
&& request.auth.token.firebase.sign_in_provider != 'anonymous';
Scanning for Auth Vulnerabilities
AuditYour.app detects misconfigured Firebase Authentication settings including open sign-up, missing email verification enforcement, and overly permissive security rules that do not properly check authentication status.
Scan your app for this vulnerability
AuditYourApp automatically detects security misconfigurations in Supabase and Firebase projects. Get actionable remediation in minutes.
Run Free ScanRelated
guides
Firebase Security Rules: The Definitive Guide
Comprehensive guide to writing secure Firebase rules
guides
BaaS Security Architecture Guide
Architectural patterns for securing backend-as-a-service applications
guides
Securing API Keys in Mobile Applications
Techniques for protecting secrets in mobile binaries