aiohttp路径遍历漏洞(CVE-2024-23334)漏洞复现
2024-03-02 03:10:54
很久没学习了~
看到这个:
https://gist.github.com/W01fh4cker/2b570b1d0df40aa94808184c231d7ecb
复现起来没什么难度:
代码位置:
1
| aiohttp.web_urldispatcher.StaticResource._handle
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| async def _handle(self, request: Request) -> StreamResponse: rel_url = request.match_info["filename"] try: filename = Path(rel_url) if filename.anchor: raise HTTPForbidden() filepath = self._directory.joinpath(filename).resolve() if not self._follow_symlinks: filepath.relative_to(self._directory) except (ValueError, FileNotFoundError) as error: raise HTTPNotFound() from error except HTTPForbidden: raise except Exception as error: request.app.logger.exception(error) raise HTTPNotFound() from error if filepath.is_dir(): if self._show_index: try: return Response( text=self._directory_as_html(filepath), content_type="text/html" ) except PermissionError: raise HTTPForbidden() else: raise HTTPForbidden() elif filepath.is_file(): return FileResponse(filepath, chunk_size=self._chunk_size) else: raise HTTPNotFound
|
为什么一定要开启 follow_symlinks
呢,因为如果不开启的话会进入 relative_to
函数。这个函数会做一些判断最后抛出一个异常:
从文字上就能看出,传递的路径必须是设定路径的子目录,例如设定路是 /tmp/static/
,那么要读的文件前缀就必须是 /tmp/static/
,否则就抛出异常了。
在上面的代码中还可以看到 _show_index
这个属性,如果同时开启了 follow_symlinks
是否可以读目录呢?答案是不行的,因为进入到这里函数以后:
1
| aiohttp.web_urldispatcher.StaticResource._directory_as_html
|
这里也做了一遍 relative_to
,然后抛出异常了。
最后就是修复了的代码了:
https://github.com/aio-libs/aiohttp/commit/9118a5831e8a65b8c839eb7e4ac983e040ff41df#diff-9632858c8fdd45d817126b2735f763b9a2e24fb2800122eb2cb0c9a3b89c85c1
看着也很简单,就是即使没有开启 _follow_symlinks
也做一次 relative_to
,里面就会自己报错了。