前言 我们的API接口都是提供给第三方服务/客户端调用,所有请求地址以及请求参数都是暴露给用户的。 我们每次请求一个HTTP请求,用户都可以通过F12,或者抓包工具fd看到请求的URL链接,然后copy出来。这样是非常不安全的,有人可能会恶意的刷我们的接口,那这时该怎么办呢?防重放攻击就出来了。 什
我们的API接口是为第三方服务/客户端调用而设计的。所有请求地址和参数都是对用户公开的。然而,每次发起HTTP请求时,用户都可以通过F12或抓包工具fd查看请求的URL链接,甚至将其复制出来。这种情况非常不安全,因为有人可能会恶意刷我们的接口。这时,防重放攻击就显得尤为重要。
防重放攻击是指通过恶意重复发送已经获取的有效数据包来攻击系统。以掘金文章点赞为例,当用户点赞后,H5会向掘金后端服务器发送请求。用户可以通过F12查看完整的请求参数,包括URL和参数等,然后将其复制出来,实施重放攻击。
具体来说,服务端返回的是重复点赞,也就是掘金并没有采取防重放攻击的措施。掘金通过查询数据库(推测item_id是唯一索引值)来判断是否已经点赞,然后返回前端逻辑。
那么,我们理解的放重放攻击是指什么呢?
简单来说,就是前端和客户端约定一个算法(比如md5),通过加密时间戳+传入字段来防止重复请求。然后,这个时间戳可以设定为30秒或60秒过期。如果30秒内有人不断刷我们的接口,我们还可以新增一个字段为nonceKey,30秒内随机不重复。这个字段存放在Redis,并且30秒过期。如果下一次请求nonceKey还在Redis中,我们就认为是重复请求,可以拒绝。
通过这样简单的算法,就可以实现防重放攻击。
防重放攻击的算法实现如下:
首先定义一个全局拦截器:
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Autowired
private StringRedisTemplate redisService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 省略部分代码
}
}
定义具体的算法实现:
public class SecretUtils {
// 省略部分代码
}
前端会通过预先约定好的算法和方式,将字符串从小到大进行排序 + timestamp,然后md5进行加密生成token传给后端。后端根据算法+方式来校验token是否有效。如果其中有人修改了参数,那么token就会校验失败,直接拒绝即可。如果没修改参数,timestamp如果大于60秒,则认为是防重放攻击,直接拒绝;如果小于30秒,则将nonceKey加入到Redis里面。这里nonceKey用的是timestamp字段,如果不存在则第一次请求,如果存在,则直接拒绝即可。
防重放攻击的Q&A:
Q:客户端和服务端生成的时间戳不一致怎么办
A:客户端和服务端生成的是时间戳,不是具体的时间。时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
Q:HTTPS数据加密是否可以防止重放攻击
A:不可以。HTTPS是在传输过程中保证了加密,也就是说如果中间人获取到了请求,他是无法解开传输的内容的。
举个最简单的例子,上课和同学传纸条的时候,为了不让中间给递纸条的人看到或者修改,可以在纸条上写成只有双方能看明白密文,这样递纸条的过程就安全了,传纸条过程中的人就看不懂你的内容了。但是如果给你写纸条的人要搞事情,那就是加密解决不了的了。这时候就需要防重放来解决了。
Q:防重放攻击是否有用,属于脱裤子放屁
A:个人感觉有一点点吧。比如防重放攻击的算法+加密方式其实大多数用的都是这些,其实攻击人很容易就能猜到token生成的方式,比如timestamp + 从小到大排序。因此我们加入了salt来混淆视听,这个salt需要前端、客户端安全的存储,不能让用户知道,比如js混淆等等。但其实通过抓包,js分析还是很容易能拿到的。但无形中增加了攻击人的成本,比如网易云登录的js加密类似。
Q:做了防重放,支付,点赞等是否不需要做幂等了
A:需要。最重要的幂等,一定要用数据库来实现,比如唯一索引。其他都不可相信。
以我个人的理解,防重放用处不大。其他安全措施,比如非对称的RSA验签更加有效。就算用户拿到了请求的所有信息,你的接口也一定要做幂等的,尤其是像支付转账等高危操作,幂等才是最有用的防线。而且防重发生成token的算法,大家都这样搞,攻击者怎么可能不知道呢?这点我不太理解。
现在面试也比较考验面试官的水平,下篇我会讲下最近的一些面试体验和感受,欢迎大家点赞收藏。
小编推荐阅读