@@ -2,9 +2,53 @@ The available methods and variables used in ``exec()`` may introduce a security
22You can restrict the use of these variables and methods by passing optional globals
33and locals parameters (dictionaries) to the ``exec() `` method.
44
5- However, use of ``exec `` is still insecure. For example, consider the following call
6- that writes a file to the user's system:
5+ However, use of ``exec() `` is still insecure if you allow some functions like
6+ ``__import__ `` or ``open ``. For example, consider the following call that writes a
7+ file to the user's system and then execute code unrestrained by the ``allowed_globals ``,
8+ or ``allowed_locals `` parameters:
79
810.. code-block :: python
911
10- exec (""" \n with open("file.txt", "w", encoding="utf-8") as file:\n file.write("# code as nefarious as imaginable")\n """ )
12+ import textwrap
13+
14+
15+ def forbid_print (* args ):
16+ raise ValueError (" This is raised when a print is used" )
17+
18+
19+ allowed_globals = {
20+ " __builtins__" : {
21+ " __import__" : __builtins__ .__import__,
22+ " open" : __builtins__ .open,
23+ " print" : forbid_print,
24+ }
25+ }
26+
27+ exec (
28+ textwrap.dedent(
29+ """
30+ import textwrap
31+
32+ with open("nefarious.py", "w") as f:
33+ f.write(textwrap.dedent('''
34+ def connive():
35+ print("Here's some code as nefarious as imaginable")
36+ '''))
37+
38+ import nefarious
39+
40+ nefarious.connive() # This will NOT raise a ValueError
41+ """
42+ ),
43+ allowed_globals,
44+ )
45+
46+
47+ The import is used only for readability of the example in this case but it could
48+ import a dangerous functions:
49+
50+ - ``subprocess.run('echo "print(\"Hello, World!\")" > nefarious.py' ``
51+ - ``pathlib.Path("nefarious.py").write_file("print(\"Hello, World!\")") ``
52+ - ``os.system('echo "print(\"Hello, World!\")" > nefarious.py') ``
53+ - ``logging.basicConfig(filename='nefarious.py'); logging.error('print("Hello, World!")') ``
54+ - etc.
0 commit comments