怎么防止用户自己调用网站 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 开发不是很懂,请问该如何防止这个情况的发生?

9659 次点击
所在节点    程序员
65 条回复
DogeFlyKite
2021-10-07 13:44:20 +08:00
搞一下 HTTPS 双向认证?
seakingii
2021-10-07 13:45:33 +08:00
首先这个话题是"矛与盾",永恒的碰撞,难说能"防止"

其次可以加一些手段加大不合法调用的难度 ,方法也是老久的

百度: api 接口签名
zmxnv123
2021-10-07 13:48:31 +08:00
token 根据 address 生成,服务端校验 token 和 address 是否匹配。
flyhaozi
2021-10-07 13:52:45 +08:00
收藏了,学习下怎么绕过接口验证😁
xiaopc
2021-10-07 13:56:22 +08:00
首先,理论上用户端发来的任何信息都应视为不可信的,总有方法可以伪造,所以终极方法是「 address 」不应由客户端发
其次,如果做不到的话,就只能提高伪造难度,比如楼上说的对请求使用某种签名,然后混淆相关代码(攻击者获得签名方式;比如使用可信介质( U 盾等)客户端证书
zjsxwc
2021-10-07 13:57:03 +08:00
用户主动行为你禁止不了。
但你可以做到不让用户之外的人恶意篡改,比如使用 https 。
mercury233
2021-10-07 13:57:18 +08:00
默认你收到的都是篡改过的值,然后该怎么办就怎么办
xiaopc
2021-10-07 14:00:34 +08:00
(点错回复了)
比如楼上说的对请求使用某种签名,然后混淆相关代码(如果攻击者获得签名方式就没用了);比如使用可信介质( U 盾等)存储的客户端证书进行签名(但是怎么保证证书不会被攻击者拿到)
lmaq
2021-10-07 14:04:10 +08:00
公钥加密+签名认证
coolrc
2021-10-07 14:08:28 +08:00
如果是用户用私有 token 发的,那这个接口应该只能改这个用户的相关 address,如果被滥用了也是用户自己主动泄漏 token 的,只会影响这个用户。

如果是公用的 token,那你的 API 应该只能 get,而不能 put 。不能给修改数据的 API 用公共 token,不然怎么样加密都会被解析出来。
chanchan
2021-10-07 14:08:31 +08:00
你觉得他不能用,他的 token 就不能有权限
Junzhou
2021-10-07 14:21:40 +08:00
他拥有他的合法 token,向接口发起请求,这样就是合法请求,为什么不能修改地址呢?

如果传递给你的地址是错误的(非法的),那你在后端对地址做校验就好了。 如果你用的是 https,把请求这个行为,和请求携带的参数是否合法,分成两个事儿来理解。 对请求内容加签只是为了保证内容在传输过程中防篡改。如果本身请求发起时携带的参数时错误的,加签并不能解决这个问题。
MintZX
2021-10-07 14:23:23 +08:00
你是想要防止入侵还是什么? 如果是防止入侵 token 就行了。如果是防止有有效身份的用户自己改信息,那基本上是不太可能的。你整套前端的代码我都能改,你怎么防╮( ̄▽ ̄"")╭
Junzhou
2021-10-07 14:26:33 +08:00
@xiaopc 5# 说的我觉得不太对,其实应该拆开了看,客户端发起的请求是可以信任的(可以做到可信),但是客户端请求携带的参数(数据),必须要假设是不可信的。
markgor
2021-10-07 14:59:46 +08:00
第一、https 和这个没关系吧。装个 Fiddler,你就算是 https 还不一样能拦截篡改。
第二、address 生成是由客户端生成,那就不存在不能篡改,你要防止篡改的话只能由服务端生成。因为客户端生成的话你无法区分 address 是被篡改后的还是没被篡改,当然你可以对参数请求进行签名,但这样无疑只是增加破解的成本而已,别人只要反编译下或者多次对比,找出你加密的规则,那最后还不是一样照篡改你的数据。
最后:前端提交的一切内容都应该视为不可信内容。
qfdk
2021-10-07 15:02:02 +08:00
这里需要后端校验用户的权限,如果用户没有更改权限,传来也没用。
首先 这个 token 要不是 jwt 的话 肯定会连着一个 previllage 的表,这里记录了一些可用的权限。正常要是 spring 的话 用 authority 来判断,默认是 访问 userinfo endpoint 来获取用户信息。 你可以用简单的 RWD 这样的三种权限来验证,看看有没有 W 权限。
当然了,还有个简单的法子,你 post 的时候, 后端通过 token,知道是谁来发送的,只要测试一下这个人是不是在白名单里面就好了 也就是

```js
if(allowEditAddress(token)){
doSomething();
}else{
// 没有权限
}
```
qfdk
2021-10-07 15:03:59 +08:00
正常来说这个 address 是客户端在发送 POST 请求的时候程序自动获取的
> 这个获取流程,移到后端呗
Jooooooooo
2021-10-07 15:05:16 +08:00
搜 验签
jinliming2
2021-10-07 15:15:42 +08:00
没有 100% 的安全。你只能增加代码逻辑混淆,通过特定的方式生成校验参数,以此来提高破解门槛。如果破解者的破解成本大于破解后的收益,就表示你的混淆有价值。
如果不考虑破解收益,用户就是想不计成本的破解你的 API 混淆参数,那么你没办法,所有前端的校验逻辑理论上都是可以被破解的。
hronro
2021-10-07 15:30:18 +08:00
你在设计 API 的时候就应该想好,不应该信任客户端传过来的任何数据

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

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

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

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

© 2021 V2EX