Skip to content

Firestore Security Rules needed - all game-state mutations (coins, hints, streaks) are client-side #163

Description

@amaydixit11

Issue

After reviewing the code, I found that canonforces uses Firebase Firestore for storing:

  • User profiles and coin balances
  • Problem submissions and completion status
  • Weekly POTD solve counts and streaks
  • Problem data (descriptions, test cases, difficulty)

Key concerns observed:

  1. Problem data in Firestore is world-writable - The QuestionBar component in src/pages/questions/[id].tsx reads problems from Firestore using getDoc(doc(db, 'questions', id)) but also uses increment(), arrayUnion(), and direct updateDoc() calls from the client side for:

    • Coin balance changes
    • Hint tracking
    • Submission counts
  2. No server-side validation of game state - Coins and streaks are modified entirely client-side:

    • setUserData with Firestore writes happen directly from the browser
    • A malicious user can modify coin balance in real-time through browser DevTools
  3. Hint cost defined client-side (HINT_COST = 10) - The cost is just a constant in the React component, not enforced by the database

Fix

The safest approach for a competitive programming platform with gamification:

  1. Use Firebase Cloud Functions for all game-state mutations:

    • User clicks "Get Hint" -> POST to Cloud Function -> Function verifies coins, deducts, returns hint
    • POTD solved -> Function verifies submission with Codeforces API -> Updates user record
  2. Set strict Firestore Security Rules:

    match /users/{userId} {
      allow read: if request.auth != null;
      allow write: if false; // Never allow clients to write user data directly
    }
    
    match /questions/{questionId} {
      allow read: if true;
      allow write: if false; // Only admin or Cloud Functions can modify
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    advancedComplex issues requiring experienced contributorsbugSomething isn't workingsecuritySecurity vulnerabilities

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions