diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py index c443b63bc9..a9f4575823 100644 --- a/django/core/serializers/pyyaml.py +++ b/django/core/serializers/pyyaml.py @@ -51,6 +51,6 @@ def Deserializer(stream_or_string, **options): stream = StringIO(stream_or_string) else: stream = stream_or_string - for obj in PythonDeserializer(yaml.load(stream), **options): + for obj in PythonDeserializer(yaml.safe_load(stream), **options): yield obj diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt index 254e85197d..c8e476263b 100644 --- a/docs/releases/1.4.txt +++ b/docs/releases/1.4.txt @@ -743,6 +743,16 @@ you can easily achieve the same by overriding the `open` method, e.g.:: def open(self, name, mode='rb'): return Spam(open(self.path(name), mode)) +YAML deserializer now uses ``yaml.safe_load`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``yaml.load`` is able to construct any Python object, which may trigger +arbitrary code execution if you process a YAML document that comes from an +untrusted source. This feature isn't necessary for Django's YAML deserializer, +whose primary use is to load fixtures consisting of simple objects. Even though +fixtures are trusted data, for additional security, the YAML deserializer now +uses ``yaml.safe_load``. + .. _deprecated-features-1.4: Features deprecated in 1.4 diff --git a/tests/modeltests/serializers/tests.py b/tests/modeltests/serializers/tests.py index 5e5a4b333a..99c065aeaf 100644 --- a/tests/modeltests/serializers/tests.py +++ b/tests/modeltests/serializers/tests.py @@ -425,7 +425,7 @@ else: @staticmethod def _validate_output(serial_str): try: - yaml.load(StringIO(serial_str)) + yaml.safe_load(StringIO(serial_str)) except Exception: return False else: @@ -435,7 +435,7 @@ else: def _get_pk_values(serial_str): ret_list = [] stream = StringIO(serial_str) - for obj_dict in yaml.load(stream): + for obj_dict in yaml.safe_load(stream): ret_list.append(obj_dict["pk"]) return ret_list @@ -443,10 +443,10 @@ else: def _get_field_values(serial_str, field_name): ret_list = [] stream = StringIO(serial_str) - for obj_dict in yaml.load(stream): + for obj_dict in yaml.safe_load(stream): if "fields" in obj_dict and field_name in obj_dict["fields"]: field_value = obj_dict["fields"][field_name] - # yaml.load will return non-string objects for some + # yaml.safe_load will return non-string objects for some # of the fields we are interested in, this ensures that # everything comes back as a string if isinstance(field_value, basestring):