Summary
The asv_benchmarks/benchmarks/common.py script is a common utility class containing a parent class from which specific benchmarks for different model types are derived. The vulnerable function loads configuration options from a configuration file but allows for overriding values in the configuration file with values set by environment variable. The SKLBENCH_JOBS variable is an integer specifying the number of concurrent jobs to execute. The script checks if the environment variable SKLBENCH_NJOBS is set, if so, it passes the variable to eval() since the values from environment variables are strings by default in Python.
Since the script uses eval() over int(), we can set the environment variable to arbitrary python code and gain execution whenever the script is run. In the example shown below, I invoke the common.py script itself, however, invoking any of the model files within that same directory (linear_models.py, svm.py, manifold.py, etc. -- anything that imports the Benchmark class) will similarly lead to execution as class variables within Benchmark invoke the vulnerable code. Accordingly, the fix is just to change to using the int() function to cast the value without additional dangerous side effects.
Severity
Low - In order for an adversary to exploit this vulnerability, they must have control over the contents of an environment variable and the script that is used for benchmarking.
Proof of Concept
~$ pwd
~$ export SKLBENCH_NJOBS='print("Code execution!")'
~$ python3 common.py
Timeline
Date reported: 02/12/2024
Date fixed: 02/22/2024
Date disclosed:03/26/2024
Summary
The asv_benchmarks/benchmarks/common.py script is a common utility class containing a parent class from which specific benchmarks for different model types are derived. The vulnerable function loads configuration options from a configuration file but allows for overriding values in the configuration file with values set by environment variable. The SKLBENCH_JOBS variable is an integer specifying the number of concurrent jobs to execute. The script checks if the environment variable SKLBENCH_NJOBS is set, if so, it passes the variable to eval() since the values from environment variables are strings by default in Python.
Since the script uses eval() over int(), we can set the environment variable to arbitrary python code and gain execution whenever the script is run. In the example shown below, I invoke the common.py script itself, however, invoking any of the model files within that same directory (linear_models.py, svm.py, manifold.py, etc. -- anything that imports the Benchmark class) will similarly lead to execution as class variables within Benchmark invoke the vulnerable code. Accordingly, the fix is just to change to using the int() function to cast the value without additional dangerous side effects.
Severity
Low - In order for an adversary to exploit this vulnerability, they must have control over the contents of an environment variable and the script that is used for benchmarking.
Proof of Concept
Timeline
Date reported: 02/12/2024
Date fixed: 02/22/2024
Date disclosed:03/26/2024