Skip to content

fix(#348): remove broad allow write from leaderboard Firestore rule#387

Merged
Aditya948351 merged 1 commit into
devpathindcommunity-india:masterfrom
anshul23102:fix/348-leaderboard-firestore-rule
May 31, 2026
Merged

fix(#348): remove broad allow write from leaderboard Firestore rule#387
Aditya948351 merged 1 commit into
devpathindcommunity-india:masterfrom
anshul23102:fix/348-leaderboard-firestore-rule

Conversation

@anshul23102
Copy link
Copy Markdown
Contributor

Summary

Fixes #348

The leaderboard/{userId} Firestore security rule had both an allow write and a field-restricted allow update clause. Firestore evaluates allow statements with OR logic, so the broader allow write always matched first for document owners, making allow update completely unreachable. This let any authenticated user write arbitrary values to their own points field directly via the Firestore client SDK.

Root cause

// Before: allow write evaluates first; allow update is never reached
match /leaderboard/{userId} {
  allow read: if true;
  allow write: if (request.auth != null && request.auth.uid == userId) || isSuperAdmin();
  allow update: if request.auth != null && request.auth.uid == userId && (
    request.resource.data.diff(resource.data).affectedKeys().hasOnly(['points'])
  );
}

Fix

// After: explicit per-operation rules; no overlapping write catch-all
match /leaderboard/{userId} {
  allow read: if true;

  // Only a superadmin (backend / Admin SDK) may create or delete entries.
  allow create, delete: if isSuperAdmin();

  // Owners may only touch the points field.
  allow update: if request.auth != null
    && request.auth.uid == userId
    && request.resource.data.diff(resource.data).affectedKeys().hasOnly(['points']);
}

Changes

  • firestore.rules: removed the allow write clause from leaderboard/{userId} and replaced it with explicit allow create, delete: if isSuperAdmin().

Security impact

  • Before: any signed-in user could call db.doc('leaderboard/<uid>').set({ points: 99999 }) and succeed.
  • After: client-side writes are limited to updating the points field only; create and delete operations require superadmin privileges.

Test plan

  • As a regular authenticated user, attempt to set an arbitrary points value via the Firestore client SDK and confirm it is rejected.
  • As a regular authenticated user, attempt to delete your leaderboard document and confirm it is rejected.
  • Confirm the leaderboard still displays correctly in the app (backend writes via Admin SDK are unaffected by these rules).
  • Confirm a superadmin can still create and delete leaderboard entries as needed.

…derboard Firestore rule

The leaderboard/{userId} rule had both an allow write and an allow update
clause. Firestore evaluates allow statements with OR logic, so the broader
allow write was always matched first for document owners. This rendered the
field-restricted allow update completely unreachable, letting any
authenticated user overwrite their own points with an arbitrary value.

Changes:
- Removed the allow write clause entirely.
- Added allow create, delete: if isSuperAdmin() so only the trusted
  backend can provision or remove leaderboard entries.
- Kept allow update scoped to the document owner with an affectedKeys
  check restricting writes to the points field only.

Fixes devpathindcommunity-india#348
Copy link
Copy Markdown
Collaborator

@Aditya948351 Aditya948351 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the broad allow write on the leaderboard is a massive security improvement. Thanks for spotting and fixing this Firestore rule!

@Aditya948351 Aditya948351 merged commit 21d601e into devpathindcommunity-india:master May 31, 2026
@Aditya948351
Copy link
Copy Markdown
Collaborator

Do star the repo! Successfully merging this and loved the changes you did.

@Aditya948351 Aditya948351 added gssoc26 This is a official GirlScript Summer of Code label. level:intermediate Intermediate level issues type:bug type:security gssoc:approved give 50+ base points labels May 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gssoc:approved give 50+ base points gssoc26 This is a official GirlScript Summer of Code label. level:intermediate Intermediate level issues type:bug type:security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Firestore leaderboard rule allows authenticated users to self-report arbitrary point values

2 participants