Skip to content

Commit 3d466b9

Browse files
authored
Merge pull request #94 from anshul23102/fix/issue-81-rule3-referral-verification
fix(security): require verified referral relationship in RULE 3 of users/{uid}
2 parents 2425002 + 69f6337 commit 3d466b9

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

firestore.rules

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,24 @@ service cloud.firestore {
7373
)
7474
);
7575

76-
// RULE 3: Referrer update - Allow another user to atomically increment a referrer's referralPoints by exactly 100 points
77-
// as part of the onboarding referral transaction.
78-
allow update: if isAuthenticated()
79-
&& request.auth.uid != uid // must be the referred user performing the write
76+
// RULE 3: Referrer update - Allow the referred user to atomically increment a referrer's
77+
// referralPoints by exactly 100 points as part of the onboarding referral transaction.
78+
// Two additional guards close the exploit described in issue #81:
79+
// 1. exists(...) confirms the referrals index document for the target user exists,
80+
// which is only created when the referrer generates a referral code.
81+
// 2. request.auth.uid in get(...).data.usedBy confirms the caller is already recorded
82+
// in the referrer's usedBy list, meaning they legitimately redeemed the referral
83+
// code before this point update fires. This prevents any arbitrary authenticated
84+
// user from granting unlimited referral points to any other user.
85+
allow update: if isAuthenticated()
86+
&& request.auth.uid != uid
8087
&& request.resource.data.points.referralPoints == resource.data.points.referralPoints + 100
8188
&& request.resource.data.points.totalPoints == resource.data.points.totalPoints + 100
8289
&& request.resource.data.points.gitRankPoints == resource.data.points.gitRankPoints
8390
&& request.resource.data.points.codingVersePoints == resource.data.points.codingVersePoints
84-
&& request.resource.data.points.streakPoints == resource.data.points.streakPoints;
91+
&& request.resource.data.points.streakPoints == resource.data.points.streakPoints
92+
&& exists(/databases/$(database)/documents/referrals/$(uid))
93+
&& request.auth.uid in get(/databases/$(database)/documents/referrals/$(uid)).data.usedBy;
8594
}
8695

8796
match /referrals/{uid} {

0 commit comments

Comments
 (0)