Skip to content

Commit 8e47a68

Browse files
committed
Use the safer safe_load function instead of unsafe_load when possible
There is no need to open ourselves up to arbitrary code execution, especially since this is not in a performance critical loop, so we can take the slowdown due to safety. PiperOrigin-RevId: 388501098 Change-Id: I3434318a5e07a798490533b554f46752397837e5
1 parent ab9fe1b commit 8e47a68

File tree

4 files changed

+18
-55
lines changed

4 files changed

+18
-55
lines changed

tensorflow/python/keras/engine/functional.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class Functional(training_lib.Model):
5858
than with subclassed `Model`s, specifically:
5959
6060
- Model cloning (`keras.models.clone`)
61-
- Serialization (`model.get_config()/from_config`, `model.to_json()/to_yaml()`
61+
- Serialization (`model.get_config()/from_config`, `model.to_json()`
6262
- Whole-model saving (`model.save()`)
6363
6464
A `Functional` model can be instantiated by passing two arguments to

tensorflow/python/keras/engine/functional_test.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,6 @@
5252
from tensorflow.python.platform import test
5353
from tensorflow.python.training.tracking.util import Checkpoint
5454

55-
try:
56-
import yaml # pylint:disable=g-import-not-at-top
57-
except ImportError:
58-
yaml = None
59-
6055

6156
class NetworkConstructionTest(keras_parameterized.TestCase):
6257

@@ -632,10 +627,6 @@ def test_multi_input_multi_output_recursion(self):
632627
json_str = model.to_json()
633628
models.model_from_json(json_str)
634629

635-
if yaml is not None:
636-
yaml_str = model.to_yaml()
637-
models.model_from_yaml(yaml_str)
638-
639630
@combinations.generate(combinations.combine(mode=['graph', 'eager']))
640631
def test_invalid_graphs(self):
641632
a = layers.Input(shape=(32,), name='input_a')
@@ -1391,10 +1382,6 @@ def test_constant_initializer_with_numpy(self):
13911382
json_str = model.to_json()
13921383
models.model_from_json(json_str)
13931384

1394-
if yaml is not None:
1395-
yaml_str = model.to_yaml()
1396-
models.model_from_yaml(yaml_str)
1397-
13981385
def test_subclassed_error_if_init_not_called(self):
13991386

14001387
class MyNetwork(training_lib.Model):

tensorflow/python/keras/engine/training.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,6 @@
9191
import h5py
9292
except ImportError:
9393
h5py = None
94-
95-
try:
96-
import yaml
97-
except ImportError:
98-
yaml = None
9994
# pylint: enable=g-import-not-at-top
10095

10196

@@ -2281,6 +2276,9 @@ def to_json(self, **kwargs):
22812276
def to_yaml(self, **kwargs):
22822277
"""Returns a yaml string containing the network configuration.
22832278
2279+
Note: Since TF 2.6, this method is no longer supported and will raise a
2280+
RuntimeError.
2281+
22842282
To load a network from a yaml save file, use
22852283
`keras.models.model_from_yaml(yaml_string, custom_objects={})`.
22862284
@@ -2296,12 +2294,12 @@ def to_yaml(self, **kwargs):
22962294
A YAML string.
22972295
22982296
Raises:
2299-
ImportError: if yaml module is not found.
2297+
RuntimeError: announces that the method poses a security risk
23002298
"""
2301-
if yaml is None:
2302-
raise ImportError(
2303-
'Requires yaml module installed (`pip install pyyaml`).')
2304-
return yaml.dump(self._updated_config(), **kwargs)
2299+
raise RuntimeError(
2300+
'Method `model.to_yaml()` has been removed due to security risk of '
2301+
'arbitrary code execution. Please use `model.to_json()` instead.'
2302+
)
23052303

23062304
def reset_states(self):
23072305
for layer in self.layers:

tensorflow/python/keras/saving/model_config.py

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,11 @@
2323

2424
from tensorflow.python.util.tf_export import keras_export
2525

26-
# pylint: disable=g-import-not-at-top
27-
try:
28-
import yaml
29-
except ImportError:
30-
yaml = None
31-
# pylint: enable=g-import-not-at-top
32-
3326

3427
@keras_export('keras.models.model_from_config')
3528
def model_from_config(config, custom_objects=None):
3629
"""Instantiates a Keras model from its config.
37-
30+
3831
Usage:
3932
```
4033
# for a Functional API model
@@ -68,17 +61,8 @@ def model_from_config(config, custom_objects=None):
6861
def model_from_yaml(yaml_string, custom_objects=None):
6962
"""Parses a yaml model configuration file and returns a model instance.
7063
71-
Usage:
72-
73-
>>> model = tf.keras.Sequential([
74-
... tf.keras.layers.Dense(5, input_shape=(3,)),
75-
... tf.keras.layers.Softmax()])
76-
>>> try:
77-
... import yaml
78-
... config = model.to_yaml()
79-
... loaded_model = tf.keras.models.model_from_yaml(config)
80-
... except ImportError:
81-
... pass
64+
Note: Since TF 2.6, this method is no longer supported and will raise a
65+
RuntimeError.
8266
8367
Arguments:
8468
yaml_string: YAML string or open file encoding a model configuration.
@@ -90,19 +74,13 @@ def model_from_yaml(yaml_string, custom_objects=None):
9074
A Keras model instance (uncompiled).
9175
9276
Raises:
93-
ImportError: if yaml module is not found.
77+
RuntimeError: announces that the method poses a security risk
9478
"""
95-
if yaml is None:
96-
raise ImportError('Requires yaml module installed (`pip install pyyaml`).')
97-
# The method unsafe_load only exists in PyYAML 5.x+, so which branch of the
98-
# try block is covered by tests depends on the installed version of PyYAML.
99-
try:
100-
# PyYAML 5.x+
101-
config = yaml.unsafe_load(yaml_string)
102-
except AttributeError:
103-
config = yaml.load(yaml_string)
104-
from tensorflow.python.keras.layers import deserialize # pylint: disable=g-import-not-at-top
105-
return deserialize(config, custom_objects=custom_objects)
79+
raise RuntimeError(
80+
'Method `model_from_yaml()` has been removed due to security risk of '
81+
'arbitrary code execution. Please use `Model.to_json()` and '
82+
'`model_from_json()` instead.'
83+
)
10684

10785

10886
@keras_export('keras.models.model_from_json')

0 commit comments

Comments
 (0)