除了防止重复提交,token 可以防止对接口的暴力请求吗?

2014-08-06 15:02:37 +08:00
 pp3182429
1. 在调用接口的时候会经常需要token,google后发现是为了防止重复请求;
2. 在返回的网页中嵌入token,很容易被获取到;有没有更高级的设计,可以防止接口被暴力请求?
3. 可以在token中加入表单校验之类的增值功能么?
14956 次点击
所在节点    程序员
26 条回复
mornlight
2014-08-06 15:06:35 +08:00
凡是发送到客户端的东西,都应该视为可以很容易被获取到。
除非是验证码这种需要识别的,但是该场景不适用。
gamexg
2014-08-06 15:53:02 +08:00
token 不是用来防止 CSRF 攻击的吗?
暴力请求指的是 ?
semicircle21
2014-08-06 15:54:25 +08:00
让客户端干点有代价的事, 比如让客户端找到x 满足 md5(token + x) -> 前3位是0的.
loading
2014-08-06 15:54:52 +08:00
是洪水 ddos?

请 lz 学习下 csrf
pp3182429
2014-08-06 17:55:16 +08:00
@gamexg 我的理解是无脑请求一个借口呀。
pp3182429
2014-08-06 17:55:50 +08:00
@semicircle21 好的,研究下。。谢谢!
pp3182429
2014-08-06 17:57:26 +08:00
@loading 唔,好。。目前在做一个金融类项目,需要考虑安全的比较多,有哪里可以系统学习一下的么?谢谢啦
Shieffan
2014-08-06 18:02:01 +08:00
最简单效果也一般用的最普遍的就是ip限制。
xoxo
2014-08-06 21:19:14 +08:00
楼上的同学们没看懂楼主的问题;
楼主说的是什么问题呢?

重复提交,表面上是重复提交,威力不大,但实际。。。我们来分析分析:


假设一个用户,余额100,平台恰好有个提现的地方,理所当然用户最多只能提取100元。

我们来分析下程序在生成提现数据的过程:

开启事务;

用户发起一次提现请求,到达应用后,程序判断用户余额是否够用,如果不够就跳出事务了;

然后扣除100元,

然后再提现数据表中插入一条数据,

到这里还没结束,因为事务还没提交,当上面进行顺利时,到达这里就应该commit提交了,如果上面操作任何一步异常,就rollback回滚了。


看起来挺完美的过程,其实!弱暴了!

为啥?



假如用户发起两个请求,而且同一时间(1/1000秒级)请求到服务器,
再走一次上面的逻辑:

请求一达到服务器 请求二达到服务器
开启事务 开启事务
余额检查->通过 余额检查->通过
扣除余额->done 扣除余额->done
插入提现记录->done 插入提现记录->done
提交->commit(); 提交->commit();


两边几乎同时进行一样的操作,为什么没被拦截掉只处理一个请求呢?因为余额检查时,别的请求的事务未提交,在此请求内select的数据还未生效,所以两个请求处理都通过了检查。



那怎么防御呢?

token?
扯J8蛋!token用来防御这原子级别的攻击?别说session了,即使你重写php底层,让session动态调用php的内存也无济于事。原因自己脑补;

队列是终极解决方案。

然后有一个临时方案,提现的表中肯定会有time/datetime之类的字段,在建表时将这个表中的time/datetime + userId 设置为联合主键,然后事务在插入提现数据时,因为时间同一秒且同一用户所以数据冲突,只会成功一条,然后事务报错启动回滚,近乎完美。唯一的瑕疵就是假如前后误差1ms, 然后恰好前一个时间是xxxx1,后一个时间是xxxx2,这样就扯痛蛋了。。。千分之一的概率。
bombless
2014-08-06 21:36:03 +08:00
hcun
bombless
2014-08-06 21:37:56 +08:00
缓存最近N次提交的ip吧,如果ip已经记录过了就更新这个ip的序号并拒绝这次提交。
aWangami
2014-08-06 22:30:11 +08:00
@xoxo 如果限制所有的操作必须要token才能完成,操作之前先请求token。对于原子操作,如果同一个账号请求过token,那么必须等账户当前token失效(操作完成),才能进行下一次请求,这样子是不是简单实现了锁机制呢?
20150517
2014-08-06 22:38:52 +08:00
@xoxo 你要复习下数据库了,余额事务操作当然是锁行,你前一个事务在做,你第二个事务根本进不了检查!这根本不是什么 php问题,是数据库问题
xoxo
2014-08-06 22:48:33 +08:00
@20150517
我所言均为线上生产代码实战总结,理论派可以去试试。
ooxxcc
2014-08-06 22:55:06 +08:00
@20150517 曾经用 @xoxo 说的方法欺负过一个页游的飘过……
wdlth
2014-08-07 00:18:57 +08:00
要考虑线程安全,即使请求同时到达,仍然通不过线程安全。还有用悲观锁,队列什么的实现。

很多页游程序为了高并发都不是线程安全的,被利用也是很常见的事……
millson
2014-08-07 07:25:38 +08:00
update `user` set `coin` = `coin` - 100 where `id` = 'xxxxxx' and `coin` > 100;

这样呢
pp3182429
2014-08-07 10:08:51 +08:00
@xoxo 谢谢xoxo的经验之谈,以前考虑简单了。
Actrace
2014-08-07 17:54:10 +08:00
原子提交,MYISAM可以锁表,InnoDB可以锁行.
pp3182429
2014-08-07 17:56:21 +08:00
@Actrace 好的,用的是mysql

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

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

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

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

© 2021 V2EX