From d05042f1a35ec0adb797c056024d457ac1fd7088 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Thu, 11 Apr 2024 15:54:45 +0100 Subject: [PATCH] Escape filenames and paths in HTML when generating index pages (#8317) (#8319) Upstream-Status: Backport [https://github.com/aio-libs/aiohttp/commit/28335525d1eac015a7e7584137678cbb6ff19397] CVE: CVE-2024-27306 Co-authored-by: J. Nick Koston (cherry picked from commit ffbc43233209df302863712b511a11bdb6001b0f) Signed-off-by: Jiaying Song --- CHANGES/8317.bugfix.rst | 1 + aiohttp/web_urldispatcher.py | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 CHANGES/8317.bugfix.rst diff --git a/CHANGES/8317.bugfix.rst b/CHANGES/8317.bugfix.rst new file mode 100644 index 0000000..b24ef2a --- /dev/null +++ b/CHANGES/8317.bugfix.rst @@ -0,0 +1 @@ +Escaped filenames in static view -- by :user:`bdraco`. diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py index e8a8023..791ab94 100644 --- a/aiohttp/web_urldispatcher.py +++ b/aiohttp/web_urldispatcher.py @@ -1,7 +1,9 @@ import abc import asyncio import base64 +import functools import hashlib +import html import inspect import keyword import os @@ -87,6 +89,7 @@ PATH_SEP: Final[str] = re.escape("/") _ExpectHandler = Callable[[Request], Awaitable[None]] _Resolve = Tuple[Optional["UrlMappingMatchInfo"], Set[str]] +html_escape = functools.partial(html.escape, quote=True) class _InfoDict(TypedDict, total=False): path: str @@ -706,7 +709,7 @@ class StaticResource(PrefixResource): assert filepath.is_dir() relative_path_to_dir = filepath.relative_to(self._directory).as_posix() - index_of = f"Index of /{relative_path_to_dir}" + index_of = f"Index of /{html_escape(relative_path_to_dir)}" h1 = f"

{index_of}

" index_list = [] @@ -714,7 +717,7 @@ class StaticResource(PrefixResource): for _file in sorted(dir_index): # show file url as relative to static path rel_path = _file.relative_to(self._directory).as_posix() - file_url = self._prefix + "/" + rel_path + quoted_file_url = _quote_path(f"{self._prefix}/{rel_path}") # if file is a directory, add '/' to the end of the name if _file.is_dir(): @@ -723,9 +726,7 @@ class StaticResource(PrefixResource): file_name = _file.name index_list.append( - '
  • {name}
  • '.format( - url=file_url, name=file_name - ) + f'
  • {html_escape(file_name)}
  • ' ) ul = "
      \n{}\n
    ".format("\n".join(index_list)) body = f"\n{h1}\n{ul}\n" -- 2.25.1