exec-used / W0122#

Message emitted:

Use of exec

Description:

Raised when the 'exec' statement is used. It's dangerous to use this function for a user input, and it's also slower than actual code in general. This doesn't mean you should never use it, but you should consider alternatives first and restrict the functions available.

Problematic code:

username = "Ada"
code_to_execute = f"""input('Enter code to be executed please, {username}: ')"""
program = exec(code_to_execute)  # [exec-used]
exec(program)  # [exec-used]

Correct code:

def get_user_code(name):
    return input(f"Enter code to be executed please, {name}: ")


username = "Ada"
allowed_globals = {"__builtins__": None}
allowed_locals = {"print": print}
# pylint: disable-next=exec-used
exec(get_user_code(username), allowed_globals, allowed_locals)

Additional details:

The available methods and variables used in exec() may introduce a security hole. You can restrict the use of these variables and methods by passing optional globals and locals parameters (dictionaries) to the exec() method.

However, use of exec is still insecure. For example, consider the following call that writes a file to the user's system:

exec("""\nwith open("file.txt", "w", encoding="utf-8") as file:\n file.write("# code as nefarious as imaginable")\n""")

Related links:

Created by the basic checker.