From f4eb87be975a5113fe7ac12f55092cebf1e2131d 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 07:48:03 +0700 Subject: [PATCH] fix(security): use of exec() to execute file contents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `calc_headers` function reads the content of `hdrs.py` and executes it using `exec(code, globs)`. While the file is from within the project, if an attacker could modify `hdrs.py` (e.g., via a supply-chain attack or compromised repository), arbitrary code would be executed during the build/code-generation process. 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..eba53f7b94b 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(), str(hdrs_file)) + 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)