diff mbox series

[meta-python,kirkstone] python3-aiohttp: fix CVE-2024-42367

Message ID 20250605091550.1472299-1-jiaying.song.cn@windriver.com
State New
Headers show
Series [meta-python,kirkstone] python3-aiohttp: fix CVE-2024-42367 | expand

Commit Message

Song, Jiaying (CN) June 5, 2025, 9:15 a.m. UTC
From: Jiaying Song <jiaying.song.cn@windriver.com>

aiohttp is an asynchronous HTTP client/server framework for asyncio and
Python. Prior to version 3.10.2, static routes which contain files with
compressed variants (`.gz` or `.br` extension) are vulnerable to path
traversal outside the root directory if those variants are symbolic
links. The server protects static routes from path traversal outside the
root directory when `follow_symlinks=False` (default). It does this by
resolving the requested URL to an absolute path and then checking that
path relative to the root. However, these checks are not performed when
looking for compressed variants in the `FileResponse` class, and
symbolic links are then automatically followed when performing the
`Path.stat()` and `Path.open()` to send the file. Version 3.10.2
contains a patch for the issue.

Reference:
https://nvd.nist.gov/vuln/detail/CVE-2024-42367
https://github.com/aio-libs/aiohttp/security/advisories/GHSA-jwhx-xcg6-8xhj

Upstream patch:
https://github.com/aio-libs/aiohttp/commit/ce2e9758814527589b10759a20783fb03b98339f

Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
---
 .../python3-aiohttp/CVE-2024-42367.patch      | 65 +++++++++++++++++++
 .../python/python3-aiohttp_3.8.6.bb           |  1 +
 2 files changed, 66 insertions(+)
 create mode 100644 meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.patch

Comments

Gyorgy Sarvari June 5, 2025, 3:40 p.m. UTC | #1
On 6/5/25 11:15, Song, Jiaying (CN) via lists.openembedded.org wrote:
> From: Jiaying Song <jiaying.song.cn@windriver.com>
>
> aiohttp is an asynchronous HTTP client/server framework for asyncio and
> Python. Prior to version 3.10.2, static routes which contain files with
> compressed variants (`.gz` or `.br` extension) are vulnerable to path
> traversal outside the root directory if those variants are symbolic
> links. The server protects static routes from path traversal outside the
> root directory when `follow_symlinks=False` (default). It does this by
> resolving the requested URL to an absolute path and then checking that
> path relative to the root. However, these checks are not performed when
> looking for compressed variants in the `FileResponse` class, and
> symbolic links are then automatically followed when performing the
> `Path.stat()` and `Path.open()` to send the file. Version 3.10.2
> contains a patch for the issue.
>
> Reference:
> https://nvd.nist.gov/vuln/detail/CVE-2024-42367
> https://github.com/aio-libs/aiohttp/security/advisories/GHSA-jwhx-xcg6-8xhj
>
> Upstream patch:
> https://github.com/aio-libs/aiohttp/commit/ce2e9758814527589b10759a20783fb03b98339f
>
> Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
> ---
>  .../python3-aiohttp/CVE-2024-42367.patch      | 65 +++++++++++++++++++
>  .../python/python3-aiohttp_3.8.6.bb           |  1 +
>  2 files changed, 66 insertions(+)
>  create mode 100644 meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.patch
>
> diff --git a/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.patch b/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.patch
> new file mode 100644
> index 0000000000..dadec31f3a
> --- /dev/null
> +++ b/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.patch
> @@ -0,0 +1,65 @@
> +From e19cb50fb529bbe75cc4f1b68eeb0a3f631ad0d0 Mon Sep 17 00:00:00 2001
> +From: "J. Nick Koston" <nick@koston.org>
> +Date: Thu, 8 Aug 2024 11:19:28 -0500
> +Subject: [PATCH] Do not follow symlinks for compressed file variants (#8652)
> +
> +CVE: CVE-2024-42367
> +
> +Upstream-Status: Backport
> +[https://github.com/aio-libs/aiohttp/commit/ce2e9758814527589b10759a20783fb03b98339f]
> +
> +Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
> +Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
> +---
> + CHANGES/8652.bugfix.rst     |  1 +
> + aiohttp/web_fileresponse.py | 26 ++++++++++++++++++++++++++
> + 2 files changed, 27 insertions(+)
> + create mode 100644 CHANGES/8652.bugfix.rst
> +
> +diff --git a/CHANGES/8652.bugfix.rst b/CHANGES/8652.bugfix.rst
> +new file mode 100644
> +index 000000000..3a1003e50
> +--- /dev/null
> ++++ b/CHANGES/8652.bugfix.rst
> +@@ -0,0 +1 @@
> ++Fixed incorrectly following symlinks for compressed file variants -- by :user:`steverep`.
> +diff --git a/aiohttp/web_fileresponse.py b/aiohttp/web_fileresponse.py
> +index f41ed3fd0..35dbd41e1 100644
> +--- a/aiohttp/web_fileresponse.py
> ++++ b/aiohttp/web_fileresponse.py
> +@@ -127,6 +127,32 @@ class FileResponse(StreamResponse):
> +         self.content_length = 0
> +         return await super().prepare(request)
> + 
> ++    def _get_file_path_stat_encoding(
> ++        self, accept_encoding: str
> ++    ) -> Tuple[pathlib.Path, os.stat_result, Optional[str]]:
> ++        """Return the file path, stat result, and encoding.
> ++
> ++        If an uncompressed file is returned, the encoding is set to
> ++        :py:data:`None`.
> ++
> ++        This method should be called from a thread executor
> ++        since it calls os.stat which may block.
> ++        """
> ++        file_path = self._path
> ++        for file_extension, file_encoding in ENCODING_EXTENSIONS.items():
> ++            if file_encoding not in accept_encoding:
> ++                continue
> ++
> ++            compressed_path = file_path.with_suffix(file_path.suffix + file_extension)
> ++            with suppress(OSError):
> ++                # Do not follow symlinks and ignore any non-regular files.
> ++                st = compressed_path.lstat()
> ++                if S_ISREG(st.st_mode):
> ++                    return compressed_path, st, file_encoding
> ++
> ++        # Fallback to the uncompressed file
> ++        return file_path, file_path.stat(), None
> ++

This doesn't look... necessary?
Is Kirkstone really affected by this CVE? If it is, then the patch
should look different - _get_file_path_stat_encoding() is a brand new
function that is introduced by this patch, but not used by anything (and
since it's prefixed with an underscore, it isn't intended to be used by
external applications). If a fix is needed, it should be somewhere else
IMO...

> +     async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter]:
> +         filepath = self._path
> + 
> +-- 
> +2.34.1
> +
> diff --git a/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb b/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb
> index 479c2f2064..fdecf9ef4c 100644
> --- a/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb
> +++ b/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb
> @@ -10,6 +10,7 @@ SRC_URI += "file://CVE-2024-23334.patch \
>              file://CVE-2024-52304.patch \
>              file://CVE-2023-49082.patch \
>              file://CVE-2024-27306.patch \
> +            file://CVE-2024-42367.patch \
>             "
>  
>  SRC_URI[sha256sum] = "b0cf2a4501bff9330a8a5248b4ce951851e415bdcce9dc158e76cfd55e15085c"
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#117748): https://lists.openembedded.org/g/openembedded-devel/message/117748
> Mute This Topic: https://lists.openembedded.org/mt/113482139/6084445
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [skandigraun@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
Song, Jiaying (CN) June 6, 2025, 3:13 a.m. UTC | #2
Hi Gyorgy,

After a careful review of the fix for python3-aiohttp_3.8.6, I believe my previous modification was not accurate.
The core issue lies in the prepare function inside web_fileresponse.py, specifically this line:
st: os.stat_result = await loop.run_in_executor(None, filepath.stat)

According to the definition of Path.stat(*, follow_symlinks=True), it follows symbolic links by default, which leads to the vulnerability described in CVE-2024-42367.

Therefore, the upstream commit:
https://github.com/aio-libs/aiohttp/commit/ce2e9758814527589b10759a20783fb03b98339f
does not directly apply as a fix to the 3.8.6 version.

I will continue to investigate and find a suitable fix for this version and will update you accordingly.

Best regards,
Jiaying 

-----Original Message-----
From: Gyorgy Sarvari <skandigraun@gmail.com> 
Sent: Thursday, June 5, 2025 11:40 PM
To: Song, Jiaying (CN) <Jiaying.Song.CN@windriver.com>; openembedded-devel@lists.openembedded.org
Cc: Li, Changqing <Changqing.Li@windriver.com>
Subject: Re: [oe] [meta-python][kirkstone][PATCH] python3-aiohttp: fix CVE-2024-42367

CAUTION: This email comes from a non Wind River email account!
Do not click links or open attachments unless you recognize the sender and know the content is safe.

On 6/5/25 11:15, Song, Jiaying (CN) via lists.openembedded.org wrote:
> From: Jiaying Song <jiaying.song.cn@windriver.com>
>
> aiohttp is an asynchronous HTTP client/server framework for asyncio 
> and Python. Prior to version 3.10.2, static routes which contain files 
> with compressed variants (`.gz` or `.br` extension) are vulnerable to 
> path traversal outside the root directory if those variants are 
> symbolic links. The server protects static routes from path traversal 
> outside the root directory when `follow_symlinks=False` (default). It 
> does this by resolving the requested URL to an absolute path and then 
> checking that path relative to the root. However, these checks are not 
> performed when looking for compressed variants in the `FileResponse` 
> class, and symbolic links are then automatically followed when 
> performing the `Path.stat()` and `Path.open()` to send the file. 
> Version 3.10.2 contains a patch for the issue.
>
> Reference:
> https://nvd.nist.gov/vuln/detail/CVE-2024-42367
> https://github.com/aio-libs/aiohttp/security/advisories/GHSA-jwhx-xcg6
> -8xhj
>
> Upstream patch:
> https://github.com/aio-libs/aiohttp/commit/ce2e9758814527589b10759a207
> 83fb03b98339f
>
> Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
> ---
>  .../python3-aiohttp/CVE-2024-42367.patch      | 65 +++++++++++++++++++
>  .../python/python3-aiohttp_3.8.6.bb           |  1 +
>  2 files changed, 66 insertions(+)
>  create mode 100644 
> meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.pat
> ch
>
> diff --git 
> a/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.p
> atch 
> b/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.p
> atch
> new file mode 100644
> index 0000000000..dadec31f3a
> --- /dev/null
> +++ b/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-423
> +++ 67.patch
> @@ -0,0 +1,65 @@
> +From e19cb50fb529bbe75cc4f1b68eeb0a3f631ad0d0 Mon Sep 17 00:00:00 
> +2001
> +From: "J. Nick Koston" <nick@koston.org>
> +Date: Thu, 8 Aug 2024 11:19:28 -0500
> +Subject: [PATCH] Do not follow symlinks for compressed file variants 
> +(#8652)
> +
> +CVE: CVE-2024-42367
> +
> +Upstream-Status: Backport
> +[https://github.com/aio-libs/aiohttp/commit/ce2e9758814527589b10759a2
> +0783fb03b98339f]
> +
> +Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
> +Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
> +---
> + CHANGES/8652.bugfix.rst     |  1 +
> + aiohttp/web_fileresponse.py | 26 ++++++++++++++++++++++++++
> + 2 files changed, 27 insertions(+)
> + create mode 100644 CHANGES/8652.bugfix.rst
> +
> +diff --git a/CHANGES/8652.bugfix.rst b/CHANGES/8652.bugfix.rst new 
> +file mode 100644 index 000000000..3a1003e50
> +--- /dev/null
> ++++ b/CHANGES/8652.bugfix.rst
> +@@ -0,0 +1 @@
> ++Fixed incorrectly following symlinks for compressed file variants -- by :user:`steverep`.
> +diff --git a/aiohttp/web_fileresponse.py 
> +b/aiohttp/web_fileresponse.py index f41ed3fd0..35dbd41e1 100644
> +--- a/aiohttp/web_fileresponse.py
> ++++ b/aiohttp/web_fileresponse.py
> +@@ -127,6 +127,32 @@ class FileResponse(StreamResponse):
> +         self.content_length = 0
> +         return await super().prepare(request)
> +
> ++    def _get_file_path_stat_encoding(
> ++        self, accept_encoding: str
> ++    ) -> Tuple[pathlib.Path, os.stat_result, Optional[str]]:
> ++        """Return the file path, stat result, and encoding.
> ++
> ++        If an uncompressed file is returned, the encoding is set to
> ++        :py:data:`None`.
> ++
> ++        This method should be called from a thread executor
> ++        since it calls os.stat which may block.
> ++        """
> ++        file_path = self._path
> ++        for file_extension, file_encoding in ENCODING_EXTENSIONS.items():
> ++            if file_encoding not in accept_encoding:
> ++                continue
> ++
> ++            compressed_path = file_path.with_suffix(file_path.suffix + file_extension)
> ++            with suppress(OSError):
> ++                # Do not follow symlinks and ignore any non-regular files.
> ++                st = compressed_path.lstat()
> ++                if S_ISREG(st.st_mode):
> ++                    return compressed_path, st, file_encoding
> ++
> ++        # Fallback to the uncompressed file
> ++        return file_path, file_path.stat(), None
> ++

This doesn't look... necessary?
Is Kirkstone really affected by this CVE? If it is, then the patch should look different - _get_file_path_stat_encoding() is a brand new function that is introduced by this patch, but not used by anything (and since it's prefixed with an underscore, it isn't intended to be used by external applications). If a fix is needed, it should be somewhere else IMO...

> +     async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter]:
> +         filepath = self._path
> +
> +--
> +2.34.1
> +
> diff --git 
> a/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb 
> b/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb
> index 479c2f2064..fdecf9ef4c 100644
> --- a/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb
> +++ b/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb
> @@ -10,6 +10,7 @@ SRC_URI += "file://CVE-2024-23334.patch \
>              file://CVE-2024-52304.patch \
>              file://CVE-2023-49082.patch \
>              file://CVE-2024-27306.patch \
> +            file://CVE-2024-42367.patch \
>             "
>
>  SRC_URI[sha256sum] = "b0cf2a4501bff9330a8a5248b4ce951851e415bdcce9dc158e76cfd55e15085c"
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#117748): 
> https://lists.openembedded.org/g/openembedded-devel/message/117748
> Mute This Topic: https://lists.openembedded.org/mt/113482139/6084445
> Group Owner: openembedded-devel+owner@lists.openembedded.org
> Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub 
> [skandigraun@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
>
diff mbox series

Patch

diff --git a/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.patch b/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.patch
new file mode 100644
index 0000000000..dadec31f3a
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-aiohttp/CVE-2024-42367.patch
@@ -0,0 +1,65 @@ 
+From e19cb50fb529bbe75cc4f1b68eeb0a3f631ad0d0 Mon Sep 17 00:00:00 2001
+From: "J. Nick Koston" <nick@koston.org>
+Date: Thu, 8 Aug 2024 11:19:28 -0500
+Subject: [PATCH] Do not follow symlinks for compressed file variants (#8652)
+
+CVE: CVE-2024-42367
+
+Upstream-Status: Backport
+[https://github.com/aio-libs/aiohttp/commit/ce2e9758814527589b10759a20783fb03b98339f]
+
+Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
+Signed-off-by: Jiaying Song <jiaying.song.cn@windriver.com>
+---
+ CHANGES/8652.bugfix.rst     |  1 +
+ aiohttp/web_fileresponse.py | 26 ++++++++++++++++++++++++++
+ 2 files changed, 27 insertions(+)
+ create mode 100644 CHANGES/8652.bugfix.rst
+
+diff --git a/CHANGES/8652.bugfix.rst b/CHANGES/8652.bugfix.rst
+new file mode 100644
+index 000000000..3a1003e50
+--- /dev/null
++++ b/CHANGES/8652.bugfix.rst
+@@ -0,0 +1 @@
++Fixed incorrectly following symlinks for compressed file variants -- by :user:`steverep`.
+diff --git a/aiohttp/web_fileresponse.py b/aiohttp/web_fileresponse.py
+index f41ed3fd0..35dbd41e1 100644
+--- a/aiohttp/web_fileresponse.py
++++ b/aiohttp/web_fileresponse.py
+@@ -127,6 +127,32 @@ class FileResponse(StreamResponse):
+         self.content_length = 0
+         return await super().prepare(request)
+ 
++    def _get_file_path_stat_encoding(
++        self, accept_encoding: str
++    ) -> Tuple[pathlib.Path, os.stat_result, Optional[str]]:
++        """Return the file path, stat result, and encoding.
++
++        If an uncompressed file is returned, the encoding is set to
++        :py:data:`None`.
++
++        This method should be called from a thread executor
++        since it calls os.stat which may block.
++        """
++        file_path = self._path
++        for file_extension, file_encoding in ENCODING_EXTENSIONS.items():
++            if file_encoding not in accept_encoding:
++                continue
++
++            compressed_path = file_path.with_suffix(file_path.suffix + file_extension)
++            with suppress(OSError):
++                # Do not follow symlinks and ignore any non-regular files.
++                st = compressed_path.lstat()
++                if S_ISREG(st.st_mode):
++                    return compressed_path, st, file_encoding
++
++        # Fallback to the uncompressed file
++        return file_path, file_path.stat(), None
++
+     async def prepare(self, request: "BaseRequest") -> Optional[AbstractStreamWriter]:
+         filepath = self._path
+ 
+-- 
+2.34.1
+
diff --git a/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb b/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb
index 479c2f2064..fdecf9ef4c 100644
--- a/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb
+++ b/meta-python/recipes-devtools/python/python3-aiohttp_3.8.6.bb
@@ -10,6 +10,7 @@  SRC_URI += "file://CVE-2024-23334.patch \
             file://CVE-2024-52304.patch \
             file://CVE-2023-49082.patch \
             file://CVE-2024-27306.patch \
+            file://CVE-2024-42367.patch \
            "
 
 SRC_URI[sha256sum] = "b0cf2a4501bff9330a8a5248b4ce951851e415bdcce9dc158e76cfd55e15085c"