Python: Code Execution Vulnerability
LowPublished Mar 26, 2024
### Summary The asv_benchmarks/benchmarks/[common.py](http://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 ...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| Scikit-learn Product | < https://github.com/scikit-learn/scikit-learn/pull/28504 | https://github.com/scikit-learn/scikit-learn/pull/28504 |
Details and references
### Summary The asv_benchmarks/benchmarks/[common.py](http://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 ```python ~$ 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
- Severity from
- GitHub (reviewed advisory)
More Google advisories
All Google| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| May 12024 | Python: Heap buffer overflow in a Pillow (PIL fork) interface to the littleCMS ICC Color Management System | Medium6.7 | 10.3.0 |
| Apr 52024 | UTM: Remote Code Execution Via Unsafe VM Handling | Medium | No fix yet |
| Apr 52024 | UTM: Unsafe URL Handling | Low | 4.5.1 |
| Apr 42024 | Microsoft Edge: Bypass of fix for CVE-2023-36880 | Low | See the advisory |
| Mar 192024 | PostgreSQL: Concurrent Refresh Privilege Escalation | Medium | 12.18 |
| Feb 212024 | PostgreSQL: Plv8 Deferred Trigger Privilege Escalation | High | No fix yet |