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.