php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #69617 PHP yaml_parse/yaml_parse_file/yaml_parse_url Unsafe Deserialization
Submitted: 2015-05-10 06:18 UTC Modified: 2015-05-18 15:23 UTC
From: johnleitch at outlook dot com Assigned: bd808 (profile)
Status: Closed Package: yaml (PECL)
PHP Version: Irrelevant OS: Irrelevant
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: johnleitch at outlook dot com
New email:
PHP Version: OS:

 

 [2015-05-10 06:18 UTC] johnleitch at outlook dot com
Description:
------------
The PHP unserialize() function is considered unsafe due to its behavior regarding class instantiation; in cases where serialized data is attacker controlled, it can be tampered with, allowing for the instantiation of arbitrary PHP classes and thus code execution via destructor.

Inversely, as per the documentation, the yaml_parse*() functions carry no such risk. In fact, among the YAML functions is yaml_parse_url, which retrieves and parses a remote YAML file. Deserialization of built-in YAML types appears safe, as the serializer utilizes arrays and scalar types, prohibiting control of instantiation. However, this limitation can be overcome with the largely undocumented !php/object extension type, which in turn invokes unserialize(), effectively making the yaml_parse* functions just as dangerous. An example follows:

<?php 
class A {
    function __destruct() {
       echo 'destructor invoked';
    }
}

yaml_parse('x: !php/object O:1:"A":0:{}');
?>

As mentioned previously, the yaml_parse_url function, which encourages the retrieval of YAML from remote endpoints, exhibits the same behavior:

<?php 
class A {
    function __destruct() {
       echo 'destructor invoked';
    }
}

yaml_parse_url('http://autosectools.com/yaml.txt');
?>

To mitigate this, it is recommended that the YAML serializer handle the !php/object type in a safe manner, such as prohibiting the deserialization of types that have destructors defined. If this is not possible, it is recommended that yaml_parse_url be removed and the documentation for the remaining yaml_* functions be updated with warnings akin to that of unserialize().

Test script:
---------------
See description.

Expected result:
----------------
See description.

Actual result:
--------------
See description.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-05-10 06:25 UTC] stas@php.net
-Type: Security +Type: Documentation Problem
 [2015-05-10 06:43 UTC] johnleitch at outlook dot com
I see this has been changed from a security bug to a doc bug. Given the implications of arbitrary instantiation, do you believe a mere warning is enough to mitigate the risk introduced by yaml_parse_url? The function is inherently dangerous, and I'm skeptical of any attempts at remediating the issue via guidance.
 [2015-05-18 05:41 UTC] bd808@php.net
-Assigned To: +Assigned To: bd808
 [2015-05-18 15:20 UTC] bd808@php.net
Automatic comment from SVN on behalf of bd808
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=336795
Log: Document unsafe deserialization and ini setting to disable

Add warnings for yaml_parse* methods that processing untrusted input is
dangerous if !php/object content is included. Processing for !php/object can
be disabled with the new yaml.decode_php ini setting.

Bug: 69617
 [2015-05-18 15:23 UTC] bd808@php.net
-Status: Assigned +Status: Closed
 [2015-05-18 15:23 UTC] bd808@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.

A new ini setting has also been introduced which can be used to disable !php/object processing. For the 1.2.0 release this setting has been left enabled by default to avoid a breaking change for users of !php/object processing. In a future 2.0 release where breaking changes are allowed this will be changed to be disabled by default.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Nov 26 06:01:31 2024 UTC