最近给做了一个项目,昨天被检测出shiro反序列化漏洞,一脸懵逼,连夜加班抢修,好在已经有很多前辈已经碰到过这个问题,给出了解决方案,这里我在记录一下,作为这次事故的总结,也可以为后来的人提供快捷的解决思路。
网上比较多的说到shiro 1.2.4之前的版本就存在反序列漏洞,上面贴出前两篇文章都详细的给出了导致漏洞的原因以及复现的过程,我这里就不在赘述,总结下来就是shiro的“记住我”的功能用到了AES加密,但是密钥是硬编码在代码里的,所以很容易拿到密钥,因为 AES 是对称加密,即加密密钥也同样是解密密钥,所以就可以通过恶意构建Cookie获取权限执行攻击命令,拿到root权限,官方解决的方案是简单的弃用了问题代码,链接:SHIRO-550: Disable remember-me functionality by default,所以建议是升级shiro版本,避免该问题,新版本到shiro 1.2.5及以上版本,就不存在硬编码密钥的问题,而改为自定义密钥,但是我看了一下我使用的shiro版本是1.4.0,按理不应该存在该问题了啊,那问题出在哪里呢,片头引用的第四篇文章里面说到了升级shiro版本后仍然存在反序列化漏洞,其原因是因为我们使用了别人的开源框架,他们在代码里会配置shiro的密钥,而关键代码可以在github上通过api search接口搜索到,从而得到一个所谓的key包,其实就是这些密钥的集合,然后用这些公开的密钥去轮流尝试,如果你用了开源的框架,而没有修改shiro的密钥,其实这就相当于你使用的shiro密钥已经泄露,这是非常危险的。
明白了问题所在,解决就很简单了:
1.确定自己使用的shiro版本要高于1.2.4;
2.在代码中全局搜索 "setCipherKey(Base64.decode(" 关键字,或者"setCipherKey"方法,Base64.decode()中的字符串就是shiro的密钥,要确保该密钥的安全性,千万不要使用公开的密钥。
因为笔者使用了一个开源的库,密钥没有修改才导致了该问题,好在虚惊一场,没有造成什么损失,但是要记住这个教训,提高安全意识啊。