Skip to content

Step 1: Understanding Security

Time: ~5 minutes | Type: Learning | Concepts: Security vulnerabilities, client vs server validation

What We're Learning

Before we write any security rules, we need to understand why client-side code is not secure and what could go wrong without proper server-side protection.

Before You Code: Ask AI First

💡 Interactive Learning:

Open your AI assistant and ask these questions. Really read the answers!

Why can't I trust security checks in my React code?
What is the difference between client-side and server-side validation?
If my app checks userId before showing todos, why do I still need security rules?
What could an attacker do if I don't have Firestore security rules?
Can you show me an example of how someone could bypass my app's UI and access Firestore directly?
What are some real-world examples of apps that were hacked due to missing security rules?

What you should learn:

  • Client-side code runs in the browser (users control it)
  • Users can open DevTools and bypass your app entirely
  • Without security rules, anyone can read/write ANY Firestore data
  • Attackers can use the browser console to call Firestore API directly
  • Real apps have leaked user data due to missing rules
  • Server-side rules are the ONLY real security

Understanding the Attack

After asking AI, make sure you understand this scenario:

Your App (Trying to Be Secure)

typescript
// Your React component
function TodosPage() {
  const { currentUser } = useAuth();

  useEffect(() => {
    // Only fetch current user's todos
    const q = query(
      collection(db, 'todos'),
      where('userId', '==', currentUser.uid)
    );
    const todos = await getDocs(q);
    setTodos(todos);
  }, []);

  return <div>{/* Display todos */}</div>;
}

You think: "I filtered by userId, so users can only see their own data!"

Attacker's Code (Bypassing Your App)

Attacker opens browser console and types:

javascript
// Import Firestore (your config is in the page source)
import { collection, getDocs } from 'firebase/firestore';
import { db } from './firebase';  // Your config is visible

// Get ALL todos from ALL users (no filter!)
const allTodos = await getDocs(collection(db, 'todos'));
allTodos.forEach(doc => {
  console.log(doc.data());  // See everyone's data!
});

Without security rules: This works. Attacker sees all users' todos.

With security rules: Firestore returns only attacker's todos (or permission denied).

What Could Go Wrong

Scenario 1: Privacy Breach

What happens:

  • User A can read User B's personal todos
  • Private information leaked (emails, addresses, notes)
  • GDPR violation (can be fined up to 4% of revenue)

Real-world: A dating app in 2018 exposed users' private messages due to missing rules. 100,000+ messages leaked.

Scenario 2: Data Manipulation

What happens:

  • Attacker deletes competitors' data
  • Changes other users' account settings
  • Modifies prices in e-commerce app

Real-world: A to-do list app let users delete others' tasks. One user deleted 50,000+ tasks before the vulnerability was fixed.

Scenario 3: Spam and Abuse

What happens:

  • Automated script creates millions of fake todos
  • Firestore bill skyrockets (you pay per read/write)
  • Database becomes unusable

Real-world: A social media app with no write limits had $10,000+ Firestore bill in one day due to spam bots.

Scenario 4: Complete Data Loss

What happens:

  • Malicious user writes script to delete all documents
  • All users' data gone forever
  • No undo, no recovery

Real-world: A classroom app lost all students' work when a student discovered they could delete any document.

Why Client-Side Validation Isn't Enough

Client-side (React) is for UX:

  • Instant feedback ("Please enter a title")
  • Preventing accidental errors
  • Making the app feel responsive

Server-side (Firestore rules) is for security:

  • Enforcing who can access what
  • Validating data integrity
  • Protecting against malicious attacks
  • Cannot be bypassed

Analogy:

Think of a bank:

  • Client-side: Friendly teller checking your ID
  • Server-side: Vault with biometric locks and cameras

The teller improves experience, but the vault is what actually keeps money safe.

Understanding Check

Before moving on, make sure you can answer these:

💡 Ask yourself (or ask AI if unsure):

  1. Can users bypass React code and access Firestore directly?
  2. Where do security rules run (browser or server)?
  3. If my app filters by userId, can attackers still access others' data without rules?
  4. What's one real-world consequence of missing security rules?
  5. What's the difference between client-side and server-side validation?

Expected answers:

  1. Yes, they can open DevTools and write their own code
  2. Server (Google's servers, not the browser)
  3. Yes, attackers can remove the filter and query everything
  4. Privacy breaches, data loss, massive bills, lawsuits, etc.
  5. Client = UX feedback; Server = actual security enforcement

What You Learned

At this point you should understand:

  • ✅ Why client-side code is not secure
  • ✅ How attackers can bypass your React app
  • ✅ What could go wrong without security rules
  • ✅ Why server-side rules are critical
  • ✅ That security rules are NOT optional

Next Step

Now that you understand why security rules matter, let's install the Firebase CLI so we can manage rules from your project:

Step 2: Install Firebase CLI →

Built for learning | Open source on GitHub