Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions skopt/space/space.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import numbers
import os
import numpy as np
import yaml

Expand Down Expand Up @@ -837,6 +838,11 @@ def from_yaml(cls, yml_path, namespace=None):
Instantiated Space object

"""
yml_path = str(yml_path)
if ".." in yml_path:
raise ValueError(
f"Path traversal is not allowed in yml_path. Received: {yml_path!r}"
)
with open(yml_path, 'rb') as f:
config = yaml.safe_load(f)

Expand Down
5 changes: 5 additions & 0 deletions skopt/tests/test_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,11 @@ def test_space_from_yaml():
tmp.close()
os.unlink(tmp.name)

def test_space_from_yaml_prevents_path_traversal():
with pytest.raises(ValueError, match="Path traversal"):
Space.from_yaml("../../../etc/passwd")


@pytest.mark.parametrize("name", [1, 1., True])
def test_dimension_with_invalid_names(name):
with pytest.raises(ValueError) as exc:
Expand Down
15 changes: 14 additions & 1 deletion skopt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from functools import wraps
from sklearn.utils import check_random_state
import numpy as np
import warnings
from scipy.optimize import OptimizeResult
from scipy.optimize import minimize as sp_minimize
from sklearn.base import is_regressor
Expand Down Expand Up @@ -148,7 +149,7 @@ def dump(res, filename, store_objective=True, **kwargs):
dump_(res, filename, **kwargs)


def load(filename, **kwargs):
def load(filename, trusted_source=False, **kwargs):
"""
Reconstruct a skopt optimization result from a file
persisted with skopt.dump.
Expand All @@ -163,6 +164,11 @@ def load(filename, **kwargs):
filename : string or `pathlib.Path`
The path of the file from which to load the optimization result.

trusted_source : bool, default=False
If False, emit a warning about the security risks of loading
untrusted pickle/joblib files, which can lead to arbitrary code
execution.

**kwargs : other keyword arguments
All other keyword arguments will be passed to `joblib.load`.

Expand All @@ -171,6 +177,13 @@ def load(filename, **kwargs):
res : `OptimizeResult`, scipy object
Reconstructed OptimizeResult instance.
"""
if not trusted_source:
warnings.warn(
"Loading an optimizer from an untrusted source can lead to "
"arbitrary code execution. Only load files from trusted sources. "
"Set trusted_source=True to suppress this warning.",
RuntimeWarning
)
return load_(filename, **kwargs)


Expand Down