From 49f8d6a4d9a7b2d302830482659b6a21590930fe Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Tue, 10 Mar 2026 15:39:20 +0000 Subject: [PATCH 1/5] Warn that overriding `__builtins__` for `eval` is not a secuirty mechanism --- Doc/library/functions.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 1d83cb6f2bb688..861723786ddbdb 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -613,10 +613,11 @@ are always available. They are listed here in alphabetical order. mappings as global and local namespace. If the *globals* dictionary is present and does not contain a value for the key ``__builtins__``, a reference to the dictionary of the built-in module :mod:`builtins` is - inserted under that key before *source* is parsed. That way you can - control what builtins are available to the executed code by inserting your - own ``__builtins__`` dictionary into *globals* before passing it to - :func:`eval`. If the *locals* mapping is omitted it defaults to the + inserted under that key before *source* is parsed. + Overriding ``__builtins__`` can be used to restrict or change the available + names, but it is **not** a security mechanism, the executed code can + still access builtins. + If the *locals* mapping is omitted it defaults to the *globals* dictionary. If both mappings are omitted, the source is executed with the *globals* and *locals* in the environment where :func:`eval` is called. Note, *eval()* will only have access to the @@ -702,9 +703,10 @@ are always available. They are listed here in alphabetical order. If the *globals* dictionary does not contain a value for the key ``__builtins__``, a reference to the dictionary of the built-in module - :mod:`builtins` is inserted under that key. That way you can control what - builtins are available to the executed code by inserting your own - ``__builtins__`` dictionary into *globals* before passing it to :func:`exec`. + :mod:`builtins` is inserted under that key. + Overriding ``__builtins__`` can be used to restrict or change the available + names, but it is **not** a security mechanism, the executed code can + still access builtins. The *closure* argument specifies a closure--a tuple of cellvars. It's only valid when the *object* is a code object containing From 6baacfb6dc6438338f3e00331660e785b6948233 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Tue, 10 Mar 2026 17:05:16 +0000 Subject: [PATCH 2/5] Seth's suggestion: may -> will --- Doc/library/functions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 861723786ddbdb..a72be625ae7ae9 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -606,7 +606,7 @@ are always available. They are listed here in alphabetical order. .. warning:: This function executes arbitrary code. Calling it with - user-supplied input may lead to security vulnerabilities. + user-supplied input will lead to security vulnerabilities. The *source* argument is parsed and evaluated as a Python expression (technically speaking, a condition list) using the *globals* and *locals* @@ -672,7 +672,7 @@ are always available. They are listed here in alphabetical order. .. warning:: This function executes arbitrary code. Calling it with - user-supplied input may lead to security vulnerabilities. + user-supplied input will lead to security vulnerabilities. This function supports dynamic execution of Python code. *source* must be either a string or a code object. If it is a string, the string is parsed as From d486584a386fae051550ff2b56faecb95d5930a8 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 10 Mar 2026 23:17:34 +0000 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Ned Batchelder --- Doc/library/functions.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index a72be625ae7ae9..566b4e8af75a40 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -615,8 +615,8 @@ are always available. They are listed here in alphabetical order. reference to the dictionary of the built-in module :mod:`builtins` is inserted under that key before *source* is parsed. Overriding ``__builtins__`` can be used to restrict or change the available - names, but it is **not** a security mechanism, the executed code can - still access builtins. + names, but this is **not** a security mechanism: the executed code can + still access all builtins. If the *locals* mapping is omitted it defaults to the *globals* dictionary. If both mappings are omitted, the source is executed with the *globals* and *locals* in the environment where @@ -672,7 +672,7 @@ are always available. They are listed here in alphabetical order. .. warning:: This function executes arbitrary code. Calling it with - user-supplied input will lead to security vulnerabilities. + untrusted user-supplied input will lead to security vulnerabilities. This function supports dynamic execution of Python code. *source* must be either a string or a code object. If it is a string, the string is parsed as @@ -705,8 +705,8 @@ are always available. They are listed here in alphabetical order. ``__builtins__``, a reference to the dictionary of the built-in module :mod:`builtins` is inserted under that key. Overriding ``__builtins__`` can be used to restrict or change the available - names, but it is **not** a security mechanism, the executed code can - still access builtins. + names, but is **not** a security mechanism: the executed code can + still access all builtins. The *closure* argument specifies a closure--a tuple of cellvars. It's only valid when the *object* is a code object containing From f69e67cc80d58ef3c81577da8e0572e606a59c6b Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 10 Mar 2026 23:18:20 +0000 Subject: [PATCH 4/5] GitHub seems to be asleep today.... --- Doc/library/functions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 566b4e8af75a40..56d8d734cc0f18 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -606,7 +606,7 @@ are always available. They are listed here in alphabetical order. .. warning:: This function executes arbitrary code. Calling it with - user-supplied input will lead to security vulnerabilities. + untrusted user-supplied input will lead to security vulnerabilities. The *source* argument is parsed and evaluated as a Python expression (technically speaking, a condition list) using the *globals* and *locals* From dd5330f270058595b862540ada527ca1262dfb2e Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Tue, 10 Mar 2026 23:23:44 +0000 Subject: [PATCH 5/5] Add "this" --- Doc/library/functions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 56d8d734cc0f18..483e5b1d8fdba7 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -705,7 +705,7 @@ are always available. They are listed here in alphabetical order. ``__builtins__``, a reference to the dictionary of the built-in module :mod:`builtins` is inserted under that key. Overriding ``__builtins__`` can be used to restrict or change the available - names, but is **not** a security mechanism: the executed code can + names, but this is **not** a security mechanism: the executed code can still access all builtins. The *closure* argument specifies a closure--a tuple of cellvars.