Do not use compile()
ID |
python.no_use_compile |
Severity |
low |
Resource |
Risky Values |
Language |
Python |
Tags |
CWE:94, NIST.SP.800-53, OWASP:2021:A3, PCI-DSS:6.5.1 |
Description
Avoid using the compile()
function with untrusted input as it can lead to code injection vulnerabilities when paired with eval()
or exec()
.
Rationale
The compile()
function in Python transforms a string of code into a code object that can be executed using exec()
or evaluated with eval()
. While this function by itself does not execute code, it becomes dangerous when it’s used with input that originates from users or other untrusted sources, especially if the output is then passed to exec()
or eval()
.
This pattern forms the basis of a classic code injection vulnerability (CWE-94: Improper Control of Generation of Code). Attackers can inject arbitrary code, leading to full compromise of the system if executed.
The following example demonstrates a vulnerable use:
user_input = input("Enter Python code: ")
code = compile(user_input, '<string>', 'exec')
exec(code)
In this scenario, an attacker could enter:
__import__('os').system('rm -rf /')
Which would be compiled and then executed, leading to a critical system operation.
Another variation, using eval
:
user_input = input("Enter an expression: ")
code = compile(user_input, '<string>', 'eval')
result = eval(code)
print(result)
This similarly allows for arbitrary code evaluation.
Remediation
Avoid using compile()
altogether with untrusted input. If dynamic code execution is absolutely required, strongly validate and sanitize the input before compiling or evaluating it. Prefer structured alternatives like ast.literal_eval()
or safer expression evaluators when applicable.
When you must allow limited user input for evaluations (e.g., mathematical expressions), use the ast
module to parse and validate the code structure before executing it.
Key remediation points: - Never compile or execute user-controlled strings directly. - Use safe evaluation libraries when dynamic evaluation is needed. - Rely on strict input validation and structural code checks (e.g., via AST).
Blocking or flagging all uses of compile()
in a SAST tool is a strong preventative control, especially when paired with contextual data flow analysis to detect if the source is user-controlled.
References
-
CWE-94 : Improper Control of Generation of Code ('Code Injection').
-
OWASP Code Injection explained.