Skip to content

Are My Firebase Security Rules Secure? Complete Testing Guide

Wondering if your Firebase security rules actually protect your data? This guide shows you exactly how to test and verify your Firebase security implementation.

Quick Security Assessment

Answer these questions:

  1. Can unauthenticated users read your data?
  2. Can users access other users' data?
  3. Do your rules validate data types and values?
  4. Can users modify critical fields like roles or timestamps?
  5. Are list/query operations properly restricted?

If you answered "I don't know" to any of these, you need to test your rules.

The fastest way to verify security:

bash
# Install
go install github.com/JacobDavidAlcock/firescan/cmd/firescan@latest

# Configure
firescan
firescan > set projectID your-project-id
firescan > set apiKey AIza...

# Test without authentication
firescan > scan --unauth --all

# Test with authentication
firescan > auth --create-account
firescan > scan --all

What FireScan checks:

  • Unauthenticated access to sensitive data
  • User isolation (can User A access User B's data?)
  • Permission boundaries
  • Common misconfiguration patterns
  • Path enumeration vulnerabilities

Method 2: Manual Testing Steps

Step 1: Test Unauthenticated Access

Open browser console on your site and try:

javascript
// Realtime Database
firebase.database().ref('users').once('value')
  .then(snap => console.log('VULNERABLE:', snap.val()))
  .catch(err => console.log('Protected:', err));

// Firestore
firebase.firestore().collection('users').get()
  .then(snap => console.log('VULNERABLE:', snap.docs.length))
  .catch(err => console.log('Protected:', err));

Expected result: Permission denied errors. If you see data, your rules are too permissive.

Step 2: Test User Isolation

Log in as User A, then try accessing User B's data:

javascript
const otherUserId = 'user-b-id-here';

// Try to read other user's data
firebase.database().ref(`users/${otherUserId}`).once('value')
  .then(snap => console.log('VULNERABLE: Can read others'))
  .catch(err => console.log('Protected'));

// Try to write to other user's data
firebase.database().ref(`users/${otherUserId}/name`).set('Hacked')
  .then(() => console.log('VULNERABLE: Can write to others'))
  .catch(err => console.log('Protected'));

Step 3: Test Data Validation

Try writing invalid data:

javascript
// Missing required fields
firebase.firestore().collection('posts').add({
  title: 'Test'
  // Missing: content, authorId, etc.
}).then(() => console.log('VULNERABLE: No validation'))
  .catch(err => console.log('Protected'));

// Invalid data types
firebase.firestore().collection('posts').add({
  title: 12345,  // Should be string
  content: null,
  authorId: { bad: 'object' }
}).then(() => console.log('VULNERABLE: No type checking'))
  .catch(err => console.log('Protected'));

Step 4: Test Field Modification

Try modifying protected fields:

javascript
const myUserId = firebase.auth().currentUser.uid;

// Try to make yourself admin
firebase.firestore().collection('users').doc(myUserId).update({
  role: 'admin',
  isAdmin: true,
  credits: 999999
}).then(() => console.log('VULNERABLE: Can modify critical fields'))
  .catch(err => console.log('Protected'));

Method 3: Firebase Emulator Testing

For local development testing:

bash
# Start emulator
firebase emulators:start

# Access Rules Playground
# Navigate to http://localhost:4000

# Test different scenarios in the UI

Red Flags That Indicate Insecure Rules

Realtime Database

json
{
  "rules": {
    ".read": true,  // ⚠️ DANGER: World-readable
    ".write": "auth != null"  // ⚠️ Any user can write anywhere
  }
}

Firestore

javascript
match /{document=**} {
  allow read, write;  // ⚠️ DANGER: No restrictions
}

match /users/{userId} {
  allow read, write: if request.auth != null;  // ⚠️ No user isolation
}

How to Fix Common Issues

Issue: World-Readable Data

Before:

json
".read": true

After:

json
".read": "auth != null"

Issue: No User Isolation

Before:

javascript
allow read, write: if request.auth != null;

After:

javascript
allow read, write: if request.auth.uid == userId;

Issue: No Data Validation

Before:

javascript
allow write: if request.auth != null;

After:

javascript
allow write: if request.auth != null
  && request.resource.data.keys().hasAll(['title', 'content'])
  && request.resource.data.title is string
  && request.resource.data.title.size() > 0;

Security Testing Checklist

  • [ ] Tested unauthenticated access (should be denied)
  • [ ] Tested cross-user data access (should be denied)
  • [ ] Tested invalid data writes (should be rejected)
  • [ ] Tested critical field modification (should be blocked)
  • [ ] Tested with multiple user accounts
  • [ ] Tested Cloud Functions authentication
  • [ ] Tested Storage bucket access
  • [ ] Reviewed rules for common patterns
  • [ ] Used automated scanning tool
  • [ ] Documented expected behavior

When to Re-Test

Test your Firebase security rules:

  • Before deploying to production
  • After any rules changes
  • When adding new features
  • After security updates
  • Monthly for production apps
  • After team members join/leave

Professional Security Assessment

Can't dedicate time to comprehensive testing? Get a professional Firebase security assessment where I'll:

  • Audit your complete Firebase implementation
  • Test all services and rules
  • Provide detailed vulnerability report
  • Give specific remediation guidance

Next Steps

Don't guess about your Firebase security. Test it properly and fix issues before attackers find them.


Support this project: Buy me a coffee or get professional help.