aiohttp目录穿越误差(CVE-2024-23334)剖析

宣布时间 2024-04-01

一、误差概述


aiohtp 是构建于 Python l/0 框架 AsyncI0 之上的开源库,用于处置惩罚无需基于古板线程网络的大宗并发HTTP请求 。aiohttp支持HTTP客户端、HTTP服务端、WebSocket客户端、WebSocket服务端、服务端中心件等 。aiohttp被普遍使用,在网络中有大宗基于该框架开发的在线系统 。

尊龙凯官网入口ADLab研究员在误差情报跟踪中发明了aiohttp目录遍历误差(CVE-2024-23334),并对其举行了深入剖析和验证 。


二、影响版本


受影响版本:<3.9.2,请相关用户尽快升级到3.9.2及以上版本 。


三、误差剖析


该误差的要害信息如下[1]:

aiohttp is an asynchronous HTTP client/server framework for asyncio and Python. When using aiohttp as a web server and configuring static routes, it is necessary to specify the root path for static files. Additionally, the option 'follow_symlinks' can be used to determine whether to follow symbolic links outside the static root directory. When 'follow_symlinks' is set to True, there is no validation to check if reading a file is within the root directory. This can lead to directory traversal vulnerabilities, resulting in unauthorized access to arbitrary files on the system, even when symlinks are not present. Disabling follow_symlinks and using a reverse proxy are encouraged mitigations. Version 3.9.2 fixes this issue.


凭证要害信息,定位到开发文档的说明[2]:


尊龙凯时 - 人生就是搏!


凭证文档形貌,follow_symlinks是一个设计上用于非生产情形的功效,并且已在文档中明确提醒启用该功效是一个清静危害 。


编写如下的示例代码,测试follow_symlinks的功效:


尊龙凯时 - 人生就是搏!


在static目录下建设符号链接d,指向其它目录d:\test(该目录下保存测试文件123.txt) 。


尊龙凯时 - 人生就是搏!


以follow_symlink=fasle的模式启动测试webserver,会见static/d/123.txt的效果如下所示(提醒找不到文件):


尊龙凯时 - 人生就是搏!


以follow_symlink=true的模式启动测试webserver,会见static/d/123.txt的效果如下所示(乐成读取文件内容):


尊龙凯时 - 人生就是搏!


显然,凭证文档的形貌,若是follow_symlink=true且保存符号链接,效果就是程序的正常预期功效 。那么,该功效是怎样被认定成误差?


误差的要害信息[1]中有一句主要形貌:误差不依赖于符号链接的保存性 。可是,在请求路径中使用不保存的符号链接,底层又怎样能会见到目的文件 。


经太过析,发明底层处置惩罚请求的要害函数如下:


尊龙凯时 - 人生就是搏!


首先,获取请求文件名(filename) 。以 GET /static/d/123.txt为例,filename就是d/123.txt 。


然后,把filename转换为Path工具,并检测该工具是否保存anchor属性 。若是保存,则拒绝会见 。在windows平台上,anchor工具就是盘符(好比d:\) 。因此,此处保存清静检测,即不允许跨盘符会见 。好比GET /static/d:\test\123.txt,会被视作不法请求而拒绝:


尊龙凯时 - 人生就是搏!


再然后,把static目录的Path工具和filename的Path工具做拼接,形成新文件路径filepath 。最后,读取filepath的数据,并返回给客户端 。


显然,若是filename包括不保存的符号链接,但能会见到目的文件,那说明工具拼接爆发了非预期的效果 。由于Path工具是标准的python类,直接单独举行测试 。


(1)设定directory=c:\test , filename = d:\test\123.txt,拼接代码和效果如下:


尊龙凯时 - 人生就是搏!


拼接效果指向目的文件d:\test\123.txt,可是fname包括anchor,无法通过前面的filename.anchor检查 。


(2)设定directory=c:\test , filename = ..\d:\test\123.txt,拼接代码和运行效果如下:


尊龙凯时 - 人生就是搏!


拼接效果读取到目的文件,且fname不包括anchor,能通过filename.anchor检查 。


(3)设定directory=c:\test , filename = ..\..\d:\test\123.txt,拼接代码和运行效果如下:


尊龙凯时 - 人生就是搏!


拼接效果也读取到了目的文件,且fname不包括anchor,能filename.anchor检查 。


因此,只要在filename之前加上..\就能直接引入盘符,违反原始功效设计中需要符号链接保存的限制,从而形成了可以读取磁盘上恣意文件的清静误差 。


四、补丁剖析


补丁要害代码如下:


尊龙凯时 - 人生就是搏!


补丁的焦点机制是:路径拼接成unresolved_path后,首先挪用normpath处置惩罚unresolved_path来形成normalized_path,然后判断normalized_path是否位于静态目录_directory之下 。


单独测试补丁机制的代码和效果如下:


尊龙凯时 - 人生就是搏!


显然,由于拼接后的路径不是static目录的子目录,以是触发了异常,导致后续代码不再读取拼接后路径下的文件,从而导致了该误差不再保存 。


补丁不影响aiohttp的符号毗连支持,由于符号链接文件必需保存于static目录之下 。使用符号链接文件来处置惩罚static资源自己就是一个潜在的清静危害,开发者仍需要引起足够的重视,审慎使用该功效 。