V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
jsdi
V2EX  ›  问与答

排行榜怎么防止恶意用户刷榜?

  •  
  •   jsdi · 2022-01-06 08:39:49 +08:00 · 4349 次点击
    这是一个创建于 812 天前的主题,其中的信息可能已经有所发展或是发生改变。
    业务需求是前端有一个网页小游戏,通过小游戏会获得一个分数,这个分数要提交到后端进行排序返回小游戏的分数排行榜。如何不使用复杂的加密算法简单的实现这个需求呢?

    刚开始是用 base64 编码,不至于那么裸奔。后来导师让我用 referer 请求头实现,只有是公司域名才能访问此接口。但是 google 发现 referer 也是可以伪造的,而且使用 referer 测试好像没法单独进行接口测试。

    请问真的可以使用 referer 实现吗?有没有其他实现方式呢?
    35 条回复    2022-01-07 09:46:43 +08:00
    murmur
        1
    murmur  
       2022-01-06 08:42:16 +08:00
    这不就是反外挂技术么,肯定得是边玩边追踪的,大概就是给开发人员一个更宽松的条件,让他在上帝模式下打出一个分数,然后以这个分数为基准,超过这个分数离谱的就得人工去核算了

    现在还没看到一个完全自动化反外挂的方案
    murmur
        2
    murmur  
       2022-01-06 08:43:44 +08:00
    当然这种方式也比不上玩家的脑洞,原神不就是各种叠 buff 搞伤害竞赛,最高都叠到 700w 了,所以官方干脆锁了伤害上限
    stormer
        3
    stormer  
       2022-01-06 08:44:50 +08:00
    纯前端提交的,你只能用 js 写个校验算法,然后要对 js 进行层层加密,这个只能防菜鸟,高手没用

    没其他方式了...所有校验前端提交的方式只能说增加伪造门槛, 不过你可以后端自己伪造分数, 让自己人排 1/2/3 名,哈哈哈
    mineralsalt
        4
    mineralsalt  
       2022-01-06 08:46:21 +08:00   ❤️ 2
    先考虑这个游戏有没有人玩吧
    jsdi
        5
    jsdi  
    OP
       2022-01-06 08:50:37 +08:00
    @murmur 安全可靠的好像就只有非对称加密可以实现,但又感觉没必要太复杂哈哈
    jsdi
        6
    jsdi  
    OP
       2022-01-06 08:51:11 +08:00
    @mineralsalt 哈哈哈应该还是有人玩的
    jsdi
        7
    jsdi  
    OP
       2022-01-06 08:51:52 +08:00
    @stormer 确实 设置一个上限是最简单的
    tomczhen
        8
    tomczhen  
       2022-01-06 08:53:41 +08:00 via Android
    领奖条件加一条:要求获奖用户直播打一次,得分至少要到获奖分数的 75%。
    :doge:
    Rheinmetal
        9
    Rheinmetal  
       2022-01-06 09:10:50 +08:00   ❤️ 2
    上传操作和随机种子 看看人能否 fuxian
    排行榜延迟显示 人工审核
    boringcc
        10
    boringcc  
       2022-01-06 09:19:21 +08:00
    要求游玩的人一边录屏摄手打
    oppoic
        11
    oppoic  
       2022-01-06 09:24:13 +08:00
    微信授权登录之后才可以玩,刷榜的碰到这种的基本就折腾了
    loading
        12
    loading  
       2022-01-06 09:43:52 +08:00   ❤️ 2
    微信绑定登陆,必须点一个广告再说。
    Celebi
        13
    Celebi  
       2022-01-06 09:59:50 +08:00
    交 5 元查看排行
    wu67
        14
    wu67  
       2022-01-06 10:19:11 +08:00
    没必要. 这种通常情况下是把游戏难度搞难一点, 然后开发的时候页面仔直接就能给你玩出极限分数了. 超出这个的基本上都难, 要么开挂, 要么是赌脸那种寿命玩法. 榜爱怎么排就怎么排, 反正统计是需要服务器资源和时间的, 你觉得不对, 那就按前面测出的极限分数, 让后台把超过这个分数太多的给 ban 了...
    by 一个曾经切过几个活动页面游戏的前端仔.
    yancy0l
        15
    yancy0l  
       2022-01-06 10:20:01 +08:00
    既然是导师的实现方案,那可能不是商业化的东西,只是产品功能需要。看了描述应该是担心 通信报文有明文数据被修改,那用加密算法挺合适的,非对称加密,完美解决问题,而且也不是特别麻烦,一般网上有 Demo 。 这样实现,更合理一些,别为了解决安全问题,去绕弯子。
    leafre
        16
    leafre  
       2022-01-06 10:23:16 +08:00
    除非把逻辑放在服务端实现,否则只能增加破解难度
    jackzhengjbs
        17
    jackzhengjbs  
       2022-01-06 10:32:58 +08:00 via Android
    啥游戏啊?我的八门神器已经饥渴难耐了
    Mutoo
        18
    Mutoo  
       2022-01-06 10:38:36 +08:00
    游戏可以实现录制功能,将客户端版本、玩家每帧操作和随机数种子记录下来,高分玩家分数与记录一并提交,后端可以用一个 headless 模拟器快速重放游戏过程,看看分数是否一致即可。
    libook
        19
    libook  
       2022-01-06 10:47:09 +08:00
    referer 没用,可以伪造。

    计分机制、加密秘钥、加密算法都放到 wasm 里,有了最终分数后用对称加密发送到服务端,服务端解密记录排序返回排行榜。

    为了避免重放请求攻击,需要在加密的时候加个时间戳,这样即便分数相同加密后的密文也会不一样,服务端解密后判断时间戳是不是在过去一定时间范围内。

    以上这么处理之后,再想刷榜就只能逆向 wasm 代码,或者从游戏玩法上面做一些外挂。
    jsdi
        20
    jsdi  
    OP
       2022-01-06 10:58:29 +08:00
    说得很好,下次别说了[:doge]
    maplerecall
        21
    maplerecall  
       2022-01-06 11:09:54 +08:00 via Android
    没用的,referer 一样可以十分简单的伪造。除非游戏主要逻辑在服务端,基本没有什么好方法能够限制客户端作弊行为,无论 web 还是原生客户端。
    ch2
        22
    ch2  
       2022-01-06 12:11:15 +08:00
    无法避免
    mxT52CRuqR6o5
        23
    mxT52CRuqR6o5  
       2022-01-06 12:18:14 +08:00
    倒是确实直接把逻辑扔 wasm 里相比在 js 层搞各种东西破解难度要大得多
    lysS
        24
    lysS  
       2022-01-06 12:20:44 +08:00
    @jsdi TLS 是防止用户访问了伪造的服务器,而且你这是网页版的,做什么都不能防止用户给你发假数据。
    Privileges
        25
    Privileges  
       2022-01-06 15:14:23 +08:00
    Referer 伪造成本太低了。。。
    oneisall8955
        26
    oneisall8955  
       2022-01-06 16:59:19 +08:00
    把菜鸟用户拦截就行了,前端代码混淆,前端上传分数接口数据非对称加密
    final7genesis
        27
    final7genesis  
       2022-01-06 17:03:14 +08:00
    @libook 感觉这个方案最靠谱些
    chashao
        28
    chashao  
       2022-01-06 19:00:35 +08:00
    实时上传玩家操作,在服务端进行玩法逻辑计算以及计算分数
    t6attack
        29
    t6attack  
       2022-01-06 19:05:22 +08:00
    终极解决方法只有一个:服务端运算。
    t6attack
        30
    t6attack  
       2022-01-06 19:34:34 +08:00
    打个形象的比方:打完游戏,分数由客户机一次提交,这就好比考完试,让学生自己判卷,然后把分数报上来。也不检查卷纸。那么这个分数排行榜?只能用作参考。不能认真。
    省时点的逻辑,就是优化排行榜:加个简单判断,把排行榜里离谱的分数过滤掉。再把短时间取得不可能分数的过滤掉。这样,排行榜看起来就能正常一点。

    为什么 PC 上外挂很多,游戏机上相对较少?因为 PC 是全功能生产工具,傻瓜式的内存修改器就 N 多种。
    不管你提交过程怎么加密,怎么防伪造。这个游戏分数是一定存在某段内存里的。我用 CE 修改器定位到分数的内存地址,做一次乘方。然后游戏结束,这个离谱的分数,经过你那复杂的加密逻辑,顺利的通过服务端,登上排行榜。你辛苦编写的加密逻辑,全都变成了无用功。
    你的程序运行在我的地盘,我对它有上帝视角。你让我自己判卷,我想判多少分就判多少分。就是这么个逻辑。
    bellx
        31
    bellx  
       2022-01-06 20:25:32 +08:00 via iPhone
    楼上也说到了,最终解就是服务端计算,前端做加密只是破解难易的区别而已
    jsdi
        32
    jsdi  
    OP
       2022-01-06 22:10:26 +08:00
    @oneisall8955 非对称加密有用吗?公钥放在客户端,用户通过翻 js 文件就可以看到加密逻辑,然后他也可以把加完密的离谱分数提交到后端,后端是没法判断的
    jsdi
        33
    jsdi  
    OP
       2022-01-06 22:12:08 +08:00
    @t6attack 确实 前端还是太裸奔了阿 底裤都让人看光了
    lawler
        34
    lawler  
       2022-01-07 08:07:23 +08:00
    就冲 ”后来导师让我用 referer 请求头实现“ 这句话。
    游戏内容都用不着抓包这么啰嗦的手法。

    请问真的可以使用 referer 实现吗?
    答:可以,但只能避免试图刷榜中的很小一部分。
    有没有其他实现方式呢?
    答:很多并不能完全阻断这种行为。所以归纳下来无非是三种方向,加密(数据、协议等方式方法尽量复杂)、记录(操作日志、录像录屏、实时数据流等尽可能详尽可追溯)和加密结合记录。
    oneisall8955
        35
    oneisall8955  
       2022-01-07 09:46:43 +08:00 via Android
    @jsdi 防菜鸟而已,一般的菜鸟看到接口要上传加密的数据就不想翻前端源码,再有混淆了前端代码也不太好找到密钥和加密算法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   994 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 20:07 · PVG 04:07 · LAX 13:07 · JFK 16:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.