From 121f5e3365da94501c6b2bec8637c42673c791b1 Mon Sep 17 00:00:00 2001 From: Neroli-realy Date: Tue, 16 Jun 2026 06:26:40 +0100 Subject: [PATCH] Validate positional-only argument names check_function_argument_names() validated regular, *args, **kwargs and keyword-only parameter names against the leading-underscore rule, but omitted positional-only parameters (those before '/'). A positional-only parameter could therefore be given a protected/injected name and a default value, shadowing an injected guard hook (_getattr_, _getitem_, _write_, _print_) so that generated guard calls resolve to an attacker-controlled local instead of the safe policy hook. --- CHANGES.rst | 5 ++++- src/RestrictedPython/transformer.py | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 537c5a8..e6b53ae 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,10 @@ Changes 8.3 (unreleased) ---------------- -- Nothing changed yet. +- Also validate positional-only argument names (parameters before ``/``) so + they cannot start with an underscore, closing a sandbox escape where a + positional-only parameter could shadow an injected protected name such as + ``_getattr_``, ``_getitem_``, ``_write_`` or ``_print_``. 8.3a1.dev0 (2026-05-29) diff --git a/src/RestrictedPython/transformer.py b/src/RestrictedPython/transformer.py index b1ec1f6..e723220 100644 --- a/src/RestrictedPython/transformer.py +++ b/src/RestrictedPython/transformer.py @@ -387,6 +387,9 @@ def check_name(self, node, name, allow_magic_methods=False): self.error(node, f'"{name}" is a reserved name.') def check_function_argument_names(self, node): + for arg in node.args.posonlyargs: + self.check_name(node, arg.arg) + for arg in node.args.args: self.check_name(node, arg.arg)