如何防护Firebase HTTPS云函数免受滥用?Android游戏余额接口安全
嘿,这个刷奖励的坑我做Android小游戏的时候踩过!对付这种滥用Firebase云函数的情况,得从**云函数端(核心)和客户端(辅助)**两头堵——毕竟客户端逻辑总有办法被逆向,真正的防线还是在后端。
这些逻辑是防刷的关键,黑客直接调用云函数时绕不开这些校验:
强制验证用户身份
一定要要求客户端传递Firebase Auth的ID Token,云函数先验证token的合法性,确保调用者是你的App的注册用户,而且token没有被篡改。示例代码:const MAX_REWARD = 1000; exports.GameFinish = functions.https.onRequest(async (req, res) => { // 从请求头或参数里获取ID Token const idToken = req.headers.authorization?.split('Bearer ')[1]; if (!idToken) { res.status(401).send('Unauthorized: No ID Token provided'); return; } try { // 验证Token,同时检查项目ID(aud字段)匹配 const decodedToken = await admin.auth().verifyIdToken(idToken, true); const uid = decodedToken.uid; // 后续逻辑... } catch (err) { res.status(403).send('Unauthorized: Invalid ID Token'); return; } });添加调用频率限制
用Firestore或实时数据库记录每个用户调用GameFinish的时间戳,限制单位时间内的调用次数(比如1分钟最多1次,每小时最多5次),超过直接拒绝。示例:// 验证完用户身份后 const userLimitRef = admin.firestore().collection('user_call_limits').doc(uid); const limitDoc = await userLimitRef.get(); if (limitDoc.exists) { const lastCallTime = limitDoc.data().last_call_timestamp; // 限制1分钟内只能调用1次 if (Date.now() - lastCallTime < 60 * 1000) { res.status(429).send('Too many requests: Please wait before claiming reward'); return; } } // 更新最新调用时间 await userLimitRef.set({ last_call_timestamp: Date.now() });验证游戏数据的合理性
绝对不能只靠客户端传的“游戏完成”信号就发奖励!要让客户端上传关键游戏数据(比如回合时长、难度等级、操作行为摘要),云函数做合理性校验:- 比如正常完成一局至少需要30秒,若客户端传的时长<5秒,直接判定作弊;
- 若客户端传的奖励金额超过
MAX_REWARD,直接截断或拒绝; - 结合游戏规则,比如难度为1的回合最多只能获得200奖励,超过就异常。
启用Firebase App Check
给云函数开启App Check,只有经过验证的你的官方Android App才能调用该函数,防止黑客用Postman、脚本等工具直接发起请求。步骤:- 在Firebase控制台启用App Check,选择Android端用SafetyNet或Recaptcha;
- 客户端集成App Check,请求时自动携带App Check Token;
- 云函数里验证Token:
const appCheckToken = req.header('X-Firebase-AppCheck'); if (!appCheckToken) { res.status(401).send('No App Check token provided'); return; } try { await admin.appCheck().verifyToken(appCheckToken); } catch (err) { res.status(403).send('Invalid App Check token'); return; }
记录并监控异常行为
把所有GameFinish的调用记录(uid、调用时间、奖励金额、游戏数据)存到Firestore或Cloud Logging,然后用Cloud Monitoring设置告警规则——比如某用户1小时内调用超过10次、单次奖励接近MAX_REWARD超过5次,就触发告警,方便你手动封禁作弊用户。
这些逻辑能增加黑客作弊的成本,挡住初级脚本或逆向者:
避免直接传递奖励金额
客户端不要传“我要拿1000奖励”,而是传递游戏结果(比如“完成了难度3的回合,耗时45秒”),由云函数根据预设规则计算奖励金额,从根源上防止客户端篡改奖励数值。本地数据加密
把游戏的关键状态(比如回合开始时间、难度等级)加密存储在本地(比如用Android的EncryptedSharedPreferences),防止黑客通过修改本地文件直接伪造“游戏完成”的状态。开启代码混淆
启用Android的R8/ProGuard代码混淆,混淆调用云函数的接口、参数名等,增加黑客逆向客户端代码的难度。本地调用限制
客户端本地也添加频率限制,比如游戏结束后1分钟内禁止再次调用云函数接口——虽然这个可以被绕过,但能挡住一些不懂逆向的初级作弊者。
内容的提问来源于stack exchange,提问作者Marcos DaSilva

