【需要重视的BUG】:偷权限的情况

Source

!!如果您生产环境用到了Blog.Core系统(本文是我自己逻辑问题,和官方没关系哈),且没有做其他修改,且没有使用Ids4认证中心来授权认证,请看完本文,并即时做系统维护。


----------------------------------------------------

82519fabb6c5800904ae966a6378afdc.png

(平台的第一个安全BUG,已修改,请更新)

7d3edec4f9c355b3172b95b119f4afd0.gif

BCVP框架,是基于:

ASP.NETCore5.0+VUE.js+IdentityServer4等核心技术,实现的前后端分离与动态认证鉴权一体化平台。

01

故事描述

通过修改令牌,可更新权限

Refresh Token.

故事源于文章开头的图片,今天QQ群中,偶然看到了大家在讨论问题,最后发现是一个小伙伴(@---)发现了系统的漏洞,这里感谢他哟,通过一系列操作会篡改自己的权限,具体的过程是这样的:

1、在Swagger中,用自己的测试账号登录,获取Token令牌;

2、在jwt.io等工具内,修改jti为超级管理员的id;

3、用更换后的令牌,去刷新令牌接口发起请求;

4、得到最终的新令牌,此刻,你已经拥有管理员权限;

相关的动图,可以参考:

a47b3972d21d8984b7d875a6851f8c11.gif

(公众号最多300帧,详细的可以自己操作)

到这里你应该能看懂了,核心的BUG就出在刷新令牌的时候,我直接硬解了TOKEN,然后获取到了数据,根据UID直接生成了新的令牌,这种思路没问题,可是技术就差了,没有做很好的集成和封装,才导致了这个问题,你可能会说,官方不是有签名校验么,当然有,只不过这个接口是匿名的

不过如果你用Ids4做认证平台是没有这个问题的,毕竟人家都考虑到了嘛,

顺着思路,大家也可以多看看,多测测,还有没有其他隐藏问题。

02

修改BUG问题

增加令牌校验

CreateEncodedSignature.

这个问题已经被解决了,具体的代码可以看我的提交记录,这里感谢@wuare老铁提供技术帮忙:

feea663c6451a04cbf3706c7817c8034.png

(已经提交到Github了,欢迎查看)

思路其实很简单,就是在获取用户信息的时候,增加一次令牌校验,看看当前令牌是否被篡改了,不过解题过程可以分享下:
1、在登录的时候,我们调用

new JwtSecurityTokenHandler().WriteToken

来生成令牌;

2、去查看Write源码,发现用

JwtTokenUtilities.CreateEncodedSignature 
    (string.Concat(rawHeader, ".", rawPayload), signingCredentials);

来生成具体的令牌;

e45acdd7d5a897822aa9bf1051a922e3.png

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框架的质量受到影响。

116aa7550ef03b78d9fe3f6f9e07aa6f.png