I am developing a multiplayer game with Firebase. Player score is recorded in firebase after each game, and also a playerTotalScore field is updated with the new total. My question: Is it possible to secure playerTotalScore field against arbitrary manipulation by the user using only firebase security rules? If so, how?
I have perused firebase security information on the firebase website at length. While I understand that it is possible to implement some complex logic in the security rules (increment a number by a given amount such as this gist , or make field insert-only ( ".write": "!data.exists()"
), none of the information seems to help in this case. Increment-only rules will not be sufficient because the score can be manipulated by being incremented multiple times. Insert-only does appear to be an option for totalScore, because that is updated after each game.
As requested by Kato, here is the specific use case.
The game I am developing is a quiz game in which players answer questions, and the players scores are displayed in real time.
During the course of the game, the score for that specific game is updated after each question by the following statement:
gameRef.child('players').child(UserId).child('score').set(gameScore)
After the game is over, the totalScore (all games played) for the player is calculated as totalScore=totalScore+gameScore
and then the players total score is updated in Firebase using the following statement:
leaderboardRef.child(userId).setWithPriority({userName:userName, totalScore:totalScore}, totalScore)
Here is the specific structure I currently have in place. This is not set in stone so I am open to changing it howsoever needed per the recommended approach to secure the data.
The score for each game played by a user(player) is stored in the following structure
<firebase_root>/app/games/<gameId>/players/<userId>/score/
<gameId>
is the firebase generated key as a result of calling firebase push() method.
<UserId>
is the firebase simplelogin uid.
The totalScore (sum of all scores for all games played) for each user(player) is stored in the following data structure
<firebase_root>/app/leaderboard/<userId>/totalScore/
leaderboard data for totalScore is set using the totalScore as priority, for query purposes
leaderboardRef.child(userId).setWithPriority({userName:userName, totalScore:totalScore}, totalScore)
Both score and totalScore are numeric integer values. That is all the detail to the current data structure that I can think of.
Firebase Security Rules work by matching a pattern against database paths, and then applying custom conditions to allow access to data at those paths. All Rules across Firebase products have a path-matching component and a conditional statement allowing read or write access.
When you create a database or storage instance in the Firebase console, you choose whether your Firebase Security Rules restrict access to your data (Locked mode) or allow anyone access (Test mode). In Cloud Firestore and Realtime Database, the default rules for Locked mode deny access to all users.
Data encryptionFirebase services encrypt data in transit using HTTPS and logically isolate customer data. In addition, several Firebase services also encrypt their data at rest: Cloud Firestore. Cloud Functions for Firebase.
I have an idea. - since this is a multiplayer game you are going to have multiple players in one particular game. this means each of the players after the game over
message is going to update the partial and total score.
In security rules you can check if the opponent has written the partial value regarding the same game. - thats would be read only access. Or you can check if all opponents partial values gives the required total number etc.
Hacker would have to come up with some elaborate plan involving control of multiple accounts and synchronising the attack.
edit:
...and I can see the further question - What about the first player to update? That could be done via intents. So first all the players write an intent to write score
where the partial score will be and once there are some values everywhere they will be clear to write the actual score.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With