1
mornlight 2014-08-06 15:06:35 +08:00 1
凡是发送到客户端的东西,都应该视为可以很容易被获取到。
除非是验证码这种需要识别的,但是该场景不适用。 |
2
gamexg 2014-08-06 15:53:02 +08:00
token 不是用来防止 CSRF 攻击的吗?
暴力请求指的是 ? |
3
semicircle21 2014-08-06 15:54:25 +08:00 1
让客户端干点有代价的事, 比如让客户端找到x 满足 md5(token + x) -> 前3位是0的.
|
4
loading 2014-08-06 15:54:52 +08:00 via Android
是洪水 ddos?
请 lz 学习下 csrf |
6
pp3182429 OP @semicircle21 好的,研究下。。谢谢!
|
8
Shieffan 2014-08-06 18:02:01 +08:00
最简单效果也一般用的最普遍的就是ip限制。
|
9
xoxo 2014-08-06 21:19:14 +08:00 1
楼上的同学们没看懂楼主的问题;
楼主说的是什么问题呢? 重复提交,表面上是重复提交,威力不大,但实际。。。我们来分析分析: 假设一个用户,余额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,这样就扯痛蛋了。。。千分之一的概率。 |
10
bombless 2014-08-06 21:36:03 +08:00
hcun
|
11
bombless 2014-08-06 21:37:56 +08:00
缓存最近N次提交的ip吧,如果ip已经记录过了就更新这个ip的序号并拒绝这次提交。
|
12
aWangami 2014-08-06 22:30:11 +08:00
@xoxo 如果限制所有的操作必须要token才能完成,操作之前先请求token。对于原子操作,如果同一个账号请求过token,那么必须等账户当前token失效(操作完成),才能进行下一次请求,这样子是不是简单实现了锁机制呢?
|
13
20150517 2014-08-06 22:38:52 +08:00
@xoxo 你要复习下数据库了,余额事务操作当然是锁行,你前一个事务在做,你第二个事务根本进不了检查!这根本不是什么 php问题,是数据库问题
|
16
wdlth 2014-08-07 00:18:57 +08:00
要考虑线程安全,即使请求同时到达,仍然通不过线程安全。还有用悲观锁,队列什么的实现。
很多页游程序为了高并发都不是线程安全的,被利用也是很常见的事…… |
17
millson 2014-08-07 07:25:38 +08:00
update `user` set `coin` = `coin` - 100 where `id` = 'xxxxxx' and `coin` > 100;
这样呢 |
19
Actrace 2014-08-07 17:54:10 +08:00
原子提交,MYISAM可以锁表,InnoDB可以锁行.
|
21
Actrace 2014-08-07 18:05:41 +08:00
@pp3182429
主要看你用什么数据库引擎了. 我个人感觉其实最大的一块可能还是来自前端请求的压力,用Token来切割有效请求效果还是不错的. 至于数据原子性提交的问题,MYIASM和InnoDB都支持锁,所以不是个问题,如果是PHP的话,已经自带队列了,同一个的PHP文件的执行请求被客户端多次发起,会阻塞后面的请求,直到这个请求完成处理,当然如果是多个客户端的话,你可能还需要增加一个查询中间件队列这些请求来规避可能带来的问题,不过只要正确运用了锁,基本上都没啥问题. |