怎么防止用户自己调用网站 API 发送 POST 请求篡改数据

2021-10-07 13:28:09 +08:00
 b00tyhunt3r

譬如我有一个 API 节点, 这个 API 接收包含 1 个参数 "address" 的 POST 请求

正常来说这个 address 是客户端在发送 POST 请求的时候程序自动获取的, 用户无法自己更改 但是如果用户自己用开发者工具之类的 call 这个 API, 在请求中传入自己有效的 Token 绕过鉴权, 和一个篡改的 address 参数, 那岂不是可以随意滥用这个 API 私自修改 address 了吗?

刚刚接触 web 开发不是很懂,请问该如何防止这个情况的发生?

9660 次点击
所在节点    程序员
65 条回复
seakingii
2021-10-07 15:36:47 +08:00
@qfdk 你们忽略了一个场景,就是正常情况下,这个地址是由移动端 GPS 得到的, 所以不存在"由后端获取 address"的说法
seakingii
2021-10-07 15:38:15 +08:00
这个场景应该是"正常情况下,这个地址是由移动端 GPS 得到"

楼主可能是为了防止用户随意更改 address,(有点像打卡 APP 防乱改地址)
pupboss
2021-10-07 15:49:15 +08:00
可以做,但是意义很小就是了,因为 address 数据追根溯源是用户产生的,只要是用户产生的数据他无论如何都能篡改,就算你堵住了 address API,用户照样可以 root 越狱后改机器的 GPS

这也就是为什么说“任何用户输入都是不可信的”,后端简单做下过滤,避免用户传的数据对业务造成影响,避免不可靠的字段造成程序 crash,基本上就已经谢天谢地了
qfdk
2021-10-07 16:02:26 +08:00
@seakingii #22 主要是楼主说的是 web 开发。没有万能的解决方案,只有一个针对于某个问题的一个方案。既然移动端来传输了,那就要考虑到移动那边了(估计楼主没到这么远呢), 你想的场景合理。要是 GPS 的情况可能要来个偏移算法,看看比如飘了多远,如果手机没电了各种情况了。 逃~~~
xiaopc
2021-10-07 16:23:01 +08:00
@Junzhou MITM 拿到请求,甚至直接在客户端做手脚,客户端请求也可以做
lscexpress
2021-10-07 16:39:13 +08:00
@zmxnv123 没关系啊,篡改数据的机器和获取 token 的机器在同一个地方
linhongye
2021-10-07 16:46:28 +08:00
是的, 没有错...
用户有 token 就是可以去操作这个东西...
今天担心用户用 api 去操作 address, 明天就得担心用户虚拟 GPS 去操作 address.
想阻止这件事, 就得去结合多个不同传感器的信息去做验证.
回头来, 核心还是要考虑业务场景. 用户改了这个东西获得了什么好处, 你们损失了哪些东西?
如果损失不大, 甚至只是减少了一些利润, 其实可以不管...
一方面, 这种用户量不大, 等这种用户多了再去管.
另一方面, 如果刚接触 web, 那可能是个新项目, 这种项目有用户来用就是胜利, 还管他怎么用呢....
stevenhawking
2021-10-07 17:48:20 +08:00
你参数都是放开给用户端 <input/> 控件的,你能给他 disabled 掉吗
ch2
2021-10-07 18:06:20 +08:00
一开始你就要考虑这种情况:
api 被逆向过,请求是用脚本发过来的
这种没办法防,但是你可以写一些规则惩罚乱搞太厉害的号
kinge
2021-10-07 18:21:42 +08:00
你不需要防止客户端请求。你只需要校验参数就行了
cs419
2021-10-07 18:31:22 +08:00
这个防不了
就类似爬虫一样 你可以加高对方的作弊成本
但无法做到绝对的阻止

如果你做到了绝对的阻止 那正常用户应该也被你拒之门外了
niubee1
2021-10-07 19:04:00 +08:00
这是个设计问题吧,首先,如果一个不需要修改的值,为啥还要客户端原封不动传回去?
liuidetmks
2021-10-07 19:35:09 +08:00
目前可用的办法就是 混淆 js 。目前混淆器好像可以做到类似于汇编了,到处跳转,属性都给你混淆了。
监控下 debugger
把运行环境,时间戳也当做参数。

但是这也只能增加对方难度,不能杜绝。
clf
2021-10-07 19:48:51 +08:00
如果这个参数不应该由用户看到和生成,那么就完全把业务逻辑放在后端。
icyalala
2021-10-07 20:19:44 +08:00
ssl pinning (也就是客户端内置证书) 来防止初级的抓包
参数签名+客户端防逆向
服务端风控,这是最主要的
根据我待过的几个公司的经验,就算大厂也基本就是这些了
整体来说就是增加成本降低风险,完全避免是不可能
zyxk
2021-10-07 20:49:42 +08:00
客户自己调用 api ,在校验合法的范围内,他随便改都可以.
我也有个疑问,怎么防止客户不使用我的前台 /客户端 . 只用 api 或 第三方客户端调用 api
或者换个说法 比如 前后端分离的 V2EX 怎么防止第三方客户端呢 ?

@xiaopc @zjsxwc @coolrc @Junzhou
@MintZX @markgor @qfdk @ch2
ch2
2021-10-07 21:00:19 +08:00
@zyxk #36 答案是没法防,微信都做不到完全防止逆向
甚至后台都不一定能检测出来请求到底是不是自己客户端发的
无非是:
1. 用一些难以伪造的签名机制对请求进行签名,不要求请求必须被签名,不签名一样能用 api(可以很有效地对付懒省事的逆向者),但是服务器可以知道这个请求是第三方发过来的
2. 以封号为手段对使用非官方客户端的用户进行惩罚,或者强制踢掉这个第三方客户端的用户
使这个第三方客户端声誉受损没人敢用
leafre
2021-10-07 21:19:30 +08:00
签名+防逆向保护签名 token,只能尽可能提高篡改门槛
rekulas
2021-10-07 22:13:19 +08:00
问题可以转换下,相当于淘宝用户都可以设置自己地址,然后问如何防止用户用工具模拟提交地址
答案当然是无法防止,只能通过各种手段提高逆向难度

毕竟对服务端来说,客户端都是“无状态”的,只要参数正确,无法识别是真客户端还是伪客户端
qfdk
2021-10-07 22:37:42 +08:00
@zyxk 只能说加大难度,简单的是加了个 reCAPTCHA,为了防止计算机系学生,随便抓取 api 来进行开发第三方客户端(为了防止假设私人代码到他们的 vps 不行的 ddos 服务器来查询成绩,课程表等等)我们的方案是通过 gateway 来处理。gateway 与前端通讯是通过 session,每次前端请求,session 会续命 4h 。gateway 那边可以通过 sessionId 获取到用户的 token,token 我们不会保存在客户端(浏览器端)。这样所有的请求都通过我们 gateway 。如果第三方 学生需要搞的话,需要做到 keep-session,也就是不停的刷新浏览器或者发请求,超级麻烦。公共 API 都是 AES 加密参数的,秘钥我们知道,学生并不知道,这样公共 api 做到一人一个 token 不会重复,他们也没法穷举。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/806211

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX