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

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

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

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

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

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

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

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

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

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

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

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