CVE-2021-45232分析(APISIX網關未授權訪問)
背景
apisix網關之前出過一個dashboard api未授權訪問漏洞 [1]:因為訪問下面兩個接口不需要身份認證,所以可以利用這兩個接口進行rce。

在剛分析這個漏洞時,我有點困惑:

filter目錄下的代碼看著像是"中間件"(或者叫"過濾器")的實現,而"中間件"應該是所有請求都會經過"中間件"的業務邏輯,那為什么訪問上面的兩個接口就沒有經過filter.AuthenticationMiddleware中間件的認證邏輯呢?為什么訪問其他接口就會經過filter.AuthenticationMiddleware中間件的認證邏輯呢?
雖然動態調試下個斷點,就能看到函數調用流程,但是我還想知道"路由"和"中間件"從web框架層來看是怎么設計的。
apisix項目用到了gin框架和droplet框架,本文記錄我對這兩個框架"路由"和"中間件"使用和設計的研究,以解決自己的疑惑。
分析
01.為什么其他接口就會經過filter.AuthenticationMiddleware中間件的邏輯?
"業務代碼"可以使用"gin框架提供的Use接口"注冊中間件,比如下面這樣

從上圖中并沒有看到filter.AuthenticationMiddleware中間件被注冊,那么為什么其他接口就會經過auth中間件的邏輯?
比如GET /apisix/admin/routes HTTP/1.1
答案在droplet庫:apisix通過droplet接口注冊了filter.AuthenticationMiddleware中間件。

這樣當訪問/apisix/admin/routes路徑時,請求會經過gin框架注冊的"中間件"、droplet注冊的"中間件"。


有一個不嚴謹的結論:上面的兩張圖中,handlers和mws數組中的所有"函數"會被依次調用。
02.為什么
/apisix/admin/migrate/export接口不會經過filter.AuthenticationMiddleware中間件的邏輯?
/apisix/admin/migrate/export路由對應的"處理函數"并不是wgin.Wraps包裝的,這樣代碼流程會不從gin框架轉移到droplet框架。

對比可以看到/apisix/admin/routes路由對應的"處理函數"是wgin.Wraps返回的,這樣代碼流程會從gin框架轉移到droplet框架。

小結:gin框架和droplet框架通過wgin.Wraps包裝的func(ctx *gin.Context)函數類型連接到了一起。
03.怎么修復的?
從這個commit[2]中可以看到:
- gin框架中
- filter.AuthenticationMiddleware中間件被添加
- droplet框架中
- filter.AuthenticationMiddleware中間件被刪除

總結
本文只零散地記錄一小部分gin和droplet框架的內部邏輯,對gin路由和中間件實現有興趣的可以看《gin框架源碼解析》[3]這篇文章。
在分析過程中感覺"實現一個web框架"非常需要"接口"或者"函數類型",比如net/http和gin框架的連接、gin框架和droplet框架的連接,都是依靠"接口"或者"函數類型"來通信。
參考鏈接:
[1]https://apisix.apache.org/zh/blog/2021/12/28/dashboard-cve-2021-45232/
[2]https://github.com/apache/apisix-dashboard/commit/b565f7cd090e9ee2043fbb726fbaae01737f83cd
[3]https://www.liwenzhou.com/posts/Go/read_gin_sourcecode/
[4]漏洞分析:
https://mp.weixin.qq.com/s/WEfuVQkhvM6k-xQH0uyNXg