php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72171 unserialize() throws a Fatal Error on inaccessible parent classes
Submitted: 2016-05-06 11:48 UTC Modified: 2016-05-10 19:52 UTC
From: php at maisqi dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.0.6 OS: Windows, Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: php at maisqi dot com
New email:
PHP Version: OS:

 

 [2016-05-06 11:48 UTC] php at maisqi dot com
Description:
------------
When unserialize() finds a non-defined class it tries to autload it; but if that succeeds, but that class' base class is not "autoloadable", a Fatal Error is thrown.

This makes the unserialize() function totally unpredictable, because we should get a couple of references to __PHP_Incomplete_Class but may just as well get the script aborted.

Test script:
---------------
<?php
// file: "test.php"
spl_autoload_register(function($className) {});
spl_autoload_register(function($className) {	require_once 'ExistingClass.php';	});

$code = 'O:13:"ExistingClass":0:{}';
$o = unserialize($code);

print_r($o);
// file ends

<?php
// file: "ExistingClass.php"
class ExistingClass extends NonExistingClass {}
// file ends


Expected result:
----------------
unserialize() should return a __PHP_Incomplete_Class object.

Actual result:
--------------
It throws a Fatal Error.

This happens in PHP 7.0.6 x64 running on Windows 8 and in PHP 5.5.33 running on Linux CentOS.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-05-06 13:32 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2016-05-06 13:32 UTC] nikic@php.net
The behavior is as intended. What you are seeing is an error generated during execution of autoloaded code -- that this error happens to be caused by an undefined class is only incidental. The autoloader might as well cause some other fatal error, throw an exception, cause an exit etc. It is not the job of the unserialize() function to deal with these failures (nor can it, in the general case).
 [2016-05-06 14:43 UTC] php at maisqi dot com
Maybe it's as intended but it's not documented that way -- the docs don't event mention the word «fatal».
And even if it were documented, the fact is that anything can happen when we're unserializing. I'd say that all programmers expect unserialize() to either success or fail, not to abort the whole script -- it's a Fatal Error not an Exception (the latter would be acceptable).

nickic, can you please make a feature request out of this? At a minimum, there's a security flaw here (it's easy to sabotage a script if we can control the data that it tries to unserialize).
 [2016-05-09 11:49 UTC] inefedor at gmail dot com
Serialized data was never intended to be trusted if it comes from user, this is a mistake to trust user input. For more information see https://www.owasp.org/index.php/Deserialization_of_untrusted_data
 [2016-05-10 19:52 UTC] php at maisqi dot com
@inefedor, I know that. Thing is, there will always be someone doing it. But this «undocumented behaviour» makes the unserialize() function unpredictable. That's not good and could be avoided.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Jun 02 02:01:29 2024 UTC