关于<脱了裤子放屁>之<重放攻击>

查看 15|回复 0
作者:giiiiiithub   
上一个帖子是因为看到了《脱了裤子放屁》那篇帖子写的,但不仅仅是因为这篇,印象中之前也看到过类似的,记不清了,也可能是无中生记了。
我也说说我的看法,不一定对,欢迎拍砖指正,只要说得对,骂一骂也没关系。(我这篇也是来秀无知的)
++++++++++++++++++++++++++
首先明确的是,重放攻击的重点在于:如果有第三方拿到一个网络请求,在不解包的情况下,重复发送该请求,会造成服务出现"安全问题"。
第一,攻击者不需要解包,因为它的假设是,攻击者(不需要/不能)从请求中抓取有用信息,也(不需要/不能)篡改请求。
第二,跟幂等的关系。幂等的意思是 n 次操作的结果等同于一次操作,是允许多次操作的,而防重放供给是不允许重复请求的,这会造成"安全隐患"。不过对于某些场景某些实现的"幂等"是可以起到防重的作用的。比如某些幂等的实现是只有第一次请求是真的在操作,后续重复请求实际上是"没有操作"的。
举个不恰当的例子:假如你有一个登录接口在登录成功后返回用户信息,内部实现也支持了幂等,即:同一个用户多次登录和一次登录的效果是等效的,session 只有一个,但是却没有考虑重放攻击的问题。再假设攻击者拦截到该登录请求,是不是攻击者在不修改请求的情况下,也可以登录系统?
第三,限流是限流,重放攻击是重放攻击。限流强调频次,重放攻击的重点不在于频次,它可能只需要一次就可以攻击成功。我们需要明确自己需要的是限流还是防重放攻击还是都需要?
第四,请求需要被加密保护或者有私钥签名是基本条件,因为如果请求不加密,也没有私钥签名/加密,一定能被攻击者构造。但是跟 https 协议本身有没有防重放攻击的支持没有关系,这两个不在同一层面。
api 请求可以是像 web 端被 https 加密保护,也可以是给第三方使用被一个"私钥"保护。
第五, 我认为这是容易造成混乱边界范围不清晰的一个点。即:"重复一个请求"指的是重复用户"发出的请求",还是说,攻击者也可以根据客户端泄露的代码等信息"构造出一条参数一摸一样的请求"。我认为是前者,
因为攻击者如果是通过查阅客户端代码构造出请求,它可以构造出任何请求。这种情况应该不在"重放攻击"范围内,重放攻击本身也是属于中间人攻击。
第六,原帖提到"token 的生成规则",说"攻击者也可以完全模拟这个 token 的生成规则,来绕过服务端"。攻击者当然可以拿到生成规则,包括生成签名的公钥。
1. 作者的方案,是客户端生成 token ,假定了攻击者能够拿到客户端的规则、可能还包括了生成签名的公钥。所以攻击者可以构造一个攻击请求。但是这不是"重放攻击"的讨论范围,这不是"拦截到请求进行重放",而是构造了一个新的请求,该请求的参数可以由攻击者任意指定。

2. 对于客户端生成 token ,因为含有:随机数、时间戳,所以服务端可以在一次处理完成之后记忆下来,在近 n 分钟内不再处理含有相同随机数、时间戳的请求。中间人自然无法重放攻击。中间人即便拦截到请求,也无法篡改其随机数、时间戳,可能是因为整个请求是加密的、也可能是因为请求含有私钥签名。
最后,原作者说:"sync ,lock ,多线程等,工作中根本用不到",作者给出的代码,很明显有一个地方因为没有用锁或者 redis 的原子操作,会导致这个代码防重失效。
且看原作者代码:
```
String s = redisService.opsForValue().get(timestamp);
if (StringUtils.isNotEmpty(s)) {
return false;
} else {
redisService.opsForValue().set(timestamp, timestamp, NONCE_DURATION, TimeUnit.MILLISECONDS);
}
```
您需要登录后才可以回帖 登录 | 立即注册

返回顶部