!!如果您生产环境用到了Blog.Core系统(本文是我自己逻辑问题,和官方没关系哈),且没有做其他修改,且没有使用Ids4认证中心来授权认证,请看完本文,并即时做系统维护。
----------------------------------------------------
(平台的第一个安全BUG,已修改,请更新)
BCVP框架,是基于:
ASP.NETCore5.0+VUE.js+IdentityServer4等核心技术,实现的前后端分离与动态认证鉴权一体化平台。
01
故事描述
通过修改令牌,可更新权限
Refresh Token.
故事源于文章开头的图片,今天QQ群中,偶然看到了大家在讨论问题,最后发现是一个小伙伴(@---)发现了系统的漏洞,这里感谢他哟,通过一系列操作会篡改自己的权限,具体的过程是这样的:
1、在Swagger中,用自己的测试账号登录,获取Token令牌;
2、在jwt.io等工具内,修改jti为超级管理员的id;
3、用更换后的令牌,去刷新令牌接口发起请求;
4、得到最终的新令牌,此刻,你已经拥有管理员权限;
相关的动图,可以参考:
(公众号最多300帧,详细的可以自己操作)
到这里你应该能看懂了,核心的BUG就出在刷新令牌的时候,我直接硬解了TOKEN,然后获取到了数据,根据UID直接生成了新的令牌,这种思路没问题,可是技术就差了,没有做很好的集成和封装,才导致了这个问题,你可能会说,官方不是有签名校验么,当然有,只不过这个接口是匿名的。
不过如果你用Ids4做认证平台是没有这个问题的,毕竟人家都考虑到了嘛,
顺着思路,大家也可以多看看,多测测,还有没有其他隐藏问题。
02
修改BUG问题
增加令牌校验
CreateEncodedSignature.
这个问题已经被解决了,具体的代码可以看我的提交记录,这里感谢@wuare老铁提供技术帮忙:
(已经提交到Github了,欢迎查看)
思路其实很简单,就是在获取用户信息的时候,增加一次令牌校验,看看当前令牌是否被篡改了,不过解题过程可以分享下:
1、在登录的时候,我们调用
new JwtSecurityTokenHandler().WriteToken
来生成令牌;
2、去查看Write源码,发现用
JwtTokenUtilities.CreateEncodedSignature (string.Concat(rawHeader, ".", rawPayload), signingCredentials);
来生成具体的令牌;
3、那我们就仿照它的这种写法,我们也对token进行解析,将头部和载荷拿出来,加盐,看看和令牌的签名是否一直;
public static bool customSafeVerify(string token)
{var jwtHandler = new JwtSecurityTokenHandler();var symmetricKeyAsBase64 = AppSecretConfig.Audience_Secret_String;var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);var signingKey = new SymmetricSecurityKey(keyByteArray);var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);var jwt = jwtHandler.ReadJwtToken(token);return jwt.RawSignature == Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(jwt.RawHeader + "." + jwt.RawPayload, signingCredentials);
}
注意下,可能会和别的类冲突,注意命名空间的引用即可。
这样就没有问题了,在刷新令牌的时候,做个判断,来看看是否被篡改了:
if (tokenModel != null && JwtHelper.customSafeVerify(token) && tokenModel.Uid > 0)
PS: 这种方案可能不是最优的,也欢迎大家多多提意见吧,集思广益哟。
好啦,本次就到这里了,还是很感谢提出这个问题的小伙伴的,不仅是让我学到了知识,更让框架更完善,加油加油!
希望本次更新没有让您对BCVP框架的质量受到影响。