如何保护HTTPs触发器功能,增加黑客的用户余额

时间:2018-04-17 11:29:16

标签: javascript firebase firebase-realtime-database firebase-authentication google-cloud-functions

我在android上有一个简单的游戏,它调用了一个HTTPS firebase云功能来增加玩家在游戏结束后的平衡,问题是我有一些黑客经常调用这个功能以增加他们的奖励,我怎么能保护这个功能被滥用了吗?我可以在客户端实现的任何逻辑吗?

// this is a simple function that increases the player's balance after the game.

const MAX_REWARD = 1000;            

  exports.GameFinish = functions.https.onRequest((req, res) => {

        if (!req.headers.authorization) {
         console.error('No Firebase ID token was passed');
         res.status(403).send('Unauthorized');
         return;
         }


        res.contentType("application/json");


        if (req.query.userID) {
            userid = req.query.userID;
        }
        else {
            return res.status(404).json({'msg': 'Error', balance: 0, errors: 'no user ID was supplied'});    
        }


        if (!req.query.award) {
            return res.status(404).json({'msg': 'Error', balance: 0, errors: 'no award was supplied'});  
        }



        var award_amount = parseInt(req.query.award);

        if( award_amount > MAX_REWARD)
        {
            console.log('rewards exceeding the max limit!', result);
            award_amount = MAX_REWARD;          
        }



        admin.auth().verifyIdToken(req.headers.authorization).then(decodedIdToken => {
            return checkUserExists(userid).then((userinfo) => {
                if(userinfo != null)
                {


                var ref_prize = admin.database().ref("/game/${userid}/total_prize");
                        ref_prize.transaction(function(totalPrize) {
                        return totalPrize + award_amount;
                        });
                }
                else 
                    // error user is not in the record
                    res.status(200).json({'msg': 'Error', balance: 0, errors:  'no such a user exists'}); 

                });

        }).catch(error => {
        console.error('Error while verifying Firebase ID token:', error);
        res.status(403).send('Unauthorized'); });   

    });

1 个答案:

答案 0 :(得分:3)

此类滥用在游戏中相当常见。您希望通过实施任何或所有这些来防范它:

  1. 传入已完成的游戏的ID,并验证每个完成的游戏只能为每个玩家计算一次。这是迄今为止最有效的改进,因为它无法在不玩游戏的情况下提高分数。
  2. 仅在响应中返回基本错误消息,并依赖于记录实际问题。这意味着攻击者将更难以通过检查错误来确定代码的工作方式。
  3. 传递有关已完成游戏的游戏玩法的信息,验证这是一组有效的动作,并确定服务器上的奖励。所以相反,玩家说“我赢了这么多分”,让他们说“我做了这些动作”。然后,您的功能决定了这些动作后的游戏状态,并确定获胜者和奖励。请注意,您可能已经在游戏过程中记录了数据库中的移动,在这种情况下,您只需要玩家传入游戏ID。
  4. 一般来说,记录动作是分析它们以检测虚假游戏的好方法。即使您今天没有进行此分析,通过移动也可以在以后执行此操作(如果需要)。
  5. 所有这些都必须在服务器中实现,例如在云功能或Firebase的服务器端安全规则中。根据定义,无法信任客户端运行代码。

    这些做法可能还有很多,但这些是第一个在脑海中浮现的想法。

    顺便说一句:祝贺游戏成功,让玩家试图破解它! : - )