From 9d50881ae5ef4d3c93b708c94376717017c4ea23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=E1=BA=A7n=20B=C3=A1ch?= <45133811+barttran2k@users.noreply.github.com> Date: Tue, 7 Apr 2026 09:38:51 +0700 Subject: [PATCH] fix(security): arbitrary code execution via exec() on file conten MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `calc_headers` function reads, compiles, and executes the content of `aiohttp/hdrs.py` using `exec(code, globs)`. If an attacker can modify `hdrs.py` (e.g., through a supply chain attack or compromised repository), arbitrary code would be executed when this tool script is run. The tool is used to generate C source files that get compiled into the library. Affected files: gen.py Signed-off-by: Trần Bách <45133811+barttran2k@users.noreply.github.com> --- tools/gen.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tools/gen.py b/tools/gen.py index cc015043985..7e5fe1028b2 100755 --- a/tools/gen.py +++ b/tools/gen.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +import ast import io import pathlib from collections import defaultdict @@ -13,10 +14,20 @@ def calc_headers(root): hdrs_file = root / "aiohttp/hdrs.py" - code = compile(hdrs_file.read_text(), str(hdrs_file), "exec") - globs = {} - exec(code, globs) - headers = [val for val in globs.values() if isinstance(val, multidict.istr)] + tree = ast.parse(hdrs_file.read_text()) + headers = [] + for node in ast.walk(tree): + if isinstance(node, ast.Assign): + value = node.value + if ( + isinstance(value, ast.Call) + and isinstance(value.func, ast.Name) + and value.func.id == "istr" + and len(value.args) == 1 + and isinstance(value.args[0], ast.Constant) + and isinstance(value.args[0].value, str) + ): + headers.append(multidict.istr(value.args[0].value)) return sorted(headers)