V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zx9481
V2EX  ›  Java

请问如何实现 http 请求防止篡改呢

  •  
  •   zx9481 · 2023-07-13 08:41:36 +08:00 · 6129 次点击
    这是一个创建于 529 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前有一个网课看视频的功能 前端需要每隔 5 分钟请求后端更新课程播放记录(学习记录),为了防止客户端篡改请求参数,请问该如何实现呢?

    48 条回复    2023-07-14 05:37:14 +08:00
    MrHyde
        1
    MrHyde  
       2023-07-13 08:47:34 +08:00 via iPhone
    https ,recaptura
    musi
        2
    musi  
       2023-07-13 08:48:58 +08:00
    直接用服务器的时间算
    dfkjgklfdjg
        3
    dfkjgklfdjg  
       2023-07-13 08:51:30 +08:00
    这个不是 HTTP 请求篡改吧?做一个心跳请求?每隔多少秒请求一次服务器接口,然后服务端去累积播放时长?这样的话,用户端就算快进、拖动进度条都不会有影响到了。
    zhangqian99
        4
    zhangqian99  
       2023-07-13 08:53:52 +08:00
    对请求信息进行加密就是了,非对称加密,RSA
    churchmice
        5
    churchmice  
       2023-07-13 09:03:50 +08:00 via Android
    @zhangqian99 https 没有用的,通信密钥是双方协商出来的,客户端当然知道密钥
    至于你说的 RSA,那是为了在协商密钥的时候被第三方窃取,防止中间人攻击的,这个又不防正在互相通信的两方
    jorneyr
        6
    jorneyr  
       2023-07-13 09:06:54 +08:00
    和前一次计时比时间差,超过 4.5M 才允许计时,在 4.5M 之内提交的计时请求就是无效的。
    liuidetmks
        7
    liuidetmks  
       2023-07-13 09:07:46 +08:00   ❤️ 2
    搞一个 activeX 控件,IE only
    npe
        8
    npe  
       2023-07-13 09:11:46 +08:00
    计算本次提交时间与上次提交时间的差值,再根据差值做判断。
    bv
        9
    bv  
       2023-07-13 09:11:49 +08:00
    csrf
    8yte
        10
    8yte  
       2023-07-13 09:12:13 +08:00 via Android
    心跳间隔调低,学习时间在服务器算总时长

    比如每隔一分钟发送一次关于视频 A 的数据包,服务器检查两次数据包间隔不能小于一分钟,否则报告异常。若视频 A 有 22 分钟,则视频 A 学习完成共需要接收 23 个包。不知道这样可不可行
    tianxin8431
        11
    tianxin8431  
       2023-07-13 09:14:17 +08:00   ❤️ 18
    这种东西没必要做的那么尽善尽美...放你的用户们一条生路吧。
    leaflxh
        12
    leaflxh  
       2023-07-13 09:18:18 +08:00
    当初研究过超星学习通,每分钟发送心跳包,内容包括当前的进度,并附上 md5(请求参数 1+请求参数 2+...)算的签名防改参数。然后服务端根据心跳包的发送时间来检测是否快进或者拖动进度条。

    没什么卵用,该自动化还是能自动化,大不了上 selenium 自动挂机
    Ianchen
        13
    Ianchen  
       2023-07-13 09:18:48 +08:00   ❤️ 1
    查看了哪些视频不应该后端早就知道了吗?为什么还要每隔 5 分钟上报?至于视频播放进度不应该是客户端自己保存吗?服务端还要做这事?而且就各大视频网站来说,完整视频都是切片的,播放到一定进度再请求接口获取下一段,这样也解决视频太大一次性传输数据过多撑爆带宽
    leaflxh
        14
    leaflxh  
       2023-07-13 09:19:14 +08:00
    @leaflxh 不过可以每隔几分钟跳一个验证码来检测是否挂机,最后接上 OCR 或者打码平台.....
    leaflxh
        15
    leaflxh  
       2023-07-13 09:21:37 +08:00
    道高一尺魔高一丈,可以一步一步的升级措施,如果接了打码平台甚至你还可以要求开双摄像头位,监控用户是否在听讲(
    oppoic
        16
    oppoic  
       2023-07-13 09:27:31 +08:00
    跟之前老婆上网课场景差不多,除了视频还有在线 word 学习资料,一节一节的,视频和课件混插着来,看完一个翻下一个,视频不能快进

    当时搜了下果然有解决方案,油猴脚本有人做了自动翻页的工具。电脑开着即可,视频播完翻下一页,课件自动滚。时长一点不差,但是人是一点没看
    mmuggle
        17
    mmuggle  
       2023-07-13 09:29:28 +08:00
    防君子不防小人。简单的请求参数加个密得了
    oppoic
        18
    oppoic  
       2023-07-13 09:36:43 +08:00
    接 16 楼回复,脚本大概这样: https://greasyfork.org/zh-CN/scripts/437781

    除非用户不会找解决方案,否则你屏蔽,脚本作者里面就更新脚本反屏蔽
    a582102953
        19
    a582102953  
       2023-07-13 09:44:33 +08:00
    如果想安全就用手机 APP 做这种,通信进行签名加密传输。如果非要 h5 页面做,就是像楼上说的分段加载,当然有插件作弊,毕竟插件是模拟人的正常行为,最恶心人的就是一段时间弹窗一个 12306 年验证码让你人工输入,保证妥妥的插件失效。但搞这种容易找打,手动🐶
    goodname
        20
    goodname  
       2023-07-13 09:46:52 +08:00
    jwt 签名就是做这个的
    lambdaq
        21
    lambdaq  
       2023-07-13 09:49:21 +08:00
    最简单的方式是只允许一个 http 连接。
    mmdsun
        22
    mmdsun  
       2023-07-13 09:52:12 +08:00
    前端请求的参数,拿到算一个 md5 之类的,得到一个 sign 值,携带请求头里面。

    后端接收数据并校验 sign 值。所以,重点是保护好前端的加密逻辑和算法。
    honamx
        23
    honamx  
       2023-07-13 10:16:28 +08:00
    后端接口做个频率校验,离上一次相隔少于 5 分钟就返回失败啥的。
    clino
        24
    clino  
       2023-07-13 10:19:09 +08:00
    自己做一个客户端软件,内置的浏览器不让用户能够随意控制
    有新版本要让用户必须升级。
    Slurp
        25
    Slurp  
       2023-07-13 10:30:45 +08:00 via iPad
    😁 只能用 jsvmp WASM OLLVM 之类的虚拟化和混淆加大逆向难度,想要破解还不是能破。
    PerFectTime
        26
    PerFectTime  
       2023-07-13 10:35:37 +08:00
    请求响应数据加密加签,提交的数据使用密文,同时提供根据规则生成的 hash ,后端解密后验证 hash 防止重放
    goodname
        27
    goodname  
       2023-07-13 10:44:28 +08:00
    想到一个方法:
    课程的学习进度,就后端校验一下本次请求的播放时长和上次请求的播放时长的差是否大于 5 分钟,不满足就拒绝这次学习进度的更新;
    课程是否学习完成,就是看后端缓存的学习记录的进度
    janus77
        28
    janus77  
       2023-07-13 10:50:49 +08:00
    直接用长连接更新进度,且只允许这一个连接可以更新进度,心跳只为 double check ,这样篡改也只能改这一个连接
    pkoukk
        29
    pkoukk  
       2023-07-13 10:55:06 +08:00
    防君子不防小人,前端发起请求的时候带参数签名,前端 JS 用 webpack 混淆压缩
    能挡住 99%的人,起码我看到这么个东西我是懒得去逆向找签名方法的。
    icyalala
        30
    icyalala  
       2023-07-13 11:01:56 +08:00
    防不了,只能不断增加用户成本,直到大部分人不愿去搞。
    Jirajine
        31
    Jirajine  
       2023-07-13 11:08:17 +08:00
    一句话:枪口抬高一寸,得饶人处且饶人。

    @tianxin8431 很奇怪,评论基本都在认真建议,少有质疑需求本身的合法性/道德性的,大概很多人人平常已经习惯做这类需求了吧。

    @Ianchen 因为这是那种强制用户使用的产品,和一般平台的需求大为不同。
    Nazz
        32
    Nazz  
       2023-07-13 11:14:25 +08:00
    对参数进行签名
    flyqie
        33
    flyqie  
       2023-07-13 11:22:25 +08:00
    wasm 试试?

    不过也不可能拦住所有,而且还有浏览器兼容性问题。

    还是那句话,得饶人处且饶人,这么玩下去对用户和你都不好。。
    nc4697
        34
    nc4697  
       2023-07-13 11:43:08 +08:00
    帮家人挂一个网站的视频。
    最开始,完全明文,随便刷
    后来升级,加密了,但是找到了秘钥,继续刷
    现在又升级,加密混淆了,折腾不动了,电脑+人工挂机。。。
    angryfish
        35
    angryfish  
       2023-07-13 11:59:28 +08:00
    服务器端算时间。每隔一分钟发一次心跳。后台累计。这个过程要注意限制提交频率,防止一下子就刷完了时间。
    jack4536251
        36
    jack4536251  
       2023-07-13 12:18:23 +08:00 via Android
    用 websocket ,每隔 5 分钟给前端推送
    AyaseEri
        37
    AyaseEri  
       2023-07-13 12:22:49 +08:00
    视频后加一场考试就行了
    akira
        38
    akira  
       2023-07-13 12:56:10 +08:00
    随便弄个加密就可以了,不用怕篡改。 明面上意思一下做到位就行了,别太较真。
    Kinnice
        39
    Kinnice  
       2023-07-13 13:25:27 +08:00
    随机时间跳一个问答,没回答直接 GG
    Ianchen
        40
    Ianchen  
       2023-07-13 14:20:27 +08:00
    @Jirajine 这种需求,那只能在后端想办法了,比如上面有人提到中间随机作业、验证码等。前端不论怎么加密,也只是增加破解难度,几乎不能完全防的住破解。

    可以的话,后端计算视频时间,对视频切片,并对切片部分进行权重分配(这个需要视频录制者或者人工来介入,可能比较麻烦一点),前端要求必须请求到所有的切片才能够查看下一个视频,这样也不在乎用户是不是快进还是多倍速学习,除非用户跳跃,跳跃就表示中间可能有一个或多个分片未加载。

    处理用户跳跃其实也有个思路:高权重片段不能被忽略加载,否则视为无效学习,至于怎么提示看产品规划。(重新学习或者告知从哪个时间段开始的学习不能跳过)。

    至于学习者的学习效果如何?来几个考试就行,我们在学校学习,不也要到某个阶段就来一场考试来判断知识的掌握情况吗?这个方案直接拿来用就行。
    shui14
        41
    shui14  
       2023-07-13 14:32:45 +08:00
    最靠谱也是难度最大的是内容加密,后端控制。B/S 结构永远无法控制客户端,你永远不能信任客户端,曾研究过 web 沙盒,基本不存在绝对的安全,包括不限于 n 个标签、注入、魔改浏览器等等,出于安全或者性能监测等等原因本质它不能锁资源全部都可以伪造
    遇到过杠精。假设钱到位不惜成本,拉下 chrome 源码自己改,本地编译
    jisuowei
        42
    jisuowei  
       2023-07-13 14:53:53 +08:00   ❤️ 1
    我劝你不要助纣为虐,好课自然有人反复听,烂课就不要浪费带宽资源了(狗头
    IDAEngine
        43
    IDAEngine  
       2023-07-13 16:22:43 +08:00
    每过几分钟就弹窗答题一次,没答题的自动重新开始
    gold2022
        44
    gold2022  
       2023-07-13 18:00:04 +08:00
    每隔一段时间短信验证,答题的话会被人收集题库后实现自动答题
    Masoud2023
        45
    Masoud2023  
       2023-07-13 18:01:27 +08:00
    请求签名就行了啊。

    但是客户端防这种东西是防不住的。
    shuimugan
        46
    shuimugan  
       2023-07-13 18:33:55 +08:00
    随便做就行了,搞这么复杂,还不是被开个虚拟机轻松秒杀,或者搞个备用机熄屏播放
    flyico
        47
    flyico  
       2023-07-13 18:53:31 +08:00
    放用户一条生路吧

    前端没有不能刷的视频,实在不行最后的办法就是上 selenium ,就如楼上某位说的,完全可以做到全自动刷视频+答题,并且用户本人压根没看一条视频,23333333

    一个典型的例子,我经常帮我老婆刷视频+答题,她们答题常用的是两个网站,二选一,自从我给她写了答题脚本以后,她们单位所有人都选了能刷视频的那个网站,另一个完全无人问津
    iceheart
        48
    iceheart  
       2023-07-14 05:37:14 +08:00 via Android
    后端吐参数的时候以私有算法做签名,
    后端收到请求时同样的方法验签。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2998 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 14:10 · PVG 22:10 · LAX 06:10 · JFK 09:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.