rfc:secure_unserialize

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Next revisionBoth sides next revision
rfc:secure_unserialize [2013/04/29 23:19] – [See also] stasrfc:secure_unserialize [2014/11/03 20:16] stas
Line 1: Line 1:
-====== PHP RFC: Secured unserialize() ======+====== PHP RFC: Filtered unserialize() ======
   * Version: 1.0   * Version: 1.0
   * Date: 2013-03-29    * Date: 2013-03-29 
   * Author: Stas Malyshev, stas@php.net   * Author: Stas Malyshev, stas@php.net
-  * Status: Draft +  * Status: In Discussion 
   * First Published at: http://wiki.php.net/rfc/secure_unserialize   * First Published at: http://wiki.php.net/rfc/secure_unserialize
   * Patch: https://github.com/php/php-src/pull/315   * Patch: https://github.com/php/php-src/pull/315
Line 10: Line 10:
 unserialize() in PHP has certain security issues, brought by the fact that serialized data can unserialize() in PHP has certain security issues, brought by the fact that serialized data can
 include objects with data, and once these objects are instantiated, destructors are called when they include objects with data, and once these objects are instantiated, destructors are called when they
-are destroyed. This could allow to inject serialized data into application which may perform actions not intended by application writer.+are destroyed. This could allow to inject serialized data into application which may perform actions not intended by application writer, such as carelessly assuming unserialized data have certain types and calling functions on them which may have different meaning for different objectsBesides destructors, functions like %%__toString%%, %%__call%%, etc. can be vulnerable. 
 + 
 +It is true that best security guidelines recommend to not use unserialize() on untrusted data, but this is mainly because of the missing filtering mechanisms in unserialize(). The fact also is that many applications depend on using unserialize() and are not going to be changed, at least in the short term, to use other mechanisms, especially in areas where object support is still needed. Thus, I think it still makes sense to provide filtered unserialize() in order to allow people reasonable alternative without having them to resort to things like PHP implementation of unserialize() (e.g. see https://github.com/piwik/piwik/blob/master/libs/upgradephp/upgrade.php#L407)  
  
 ===== Proposal ===== ===== Proposal =====
Line 20: Line 22:
   * true - default value, allows all objects just as before   * true - default value, allows all objects just as before
   * false - no objects allowed   * false - no objects allowed
-  * array of class names, which list the allowed classes for unserialized objects+  * array of class names, which list the allowed classes for unserialized objects (empty array here means the same as false)
  
 If the class for the object is not allowed, the object is unserialized as an object of "incomplete class", just as it is done in a case where object's class does not exist. This means that the serialized data are roundtrip-safe with any settings, but with added security settings the unintended objects will not be accessible and their destructors and other methods will not be called.  If the class for the object is not allowed, the object is unserialized as an object of "incomplete class", just as it is done in a case where object's class does not exist. This means that the serialized data are roundtrip-safe with any settings, but with added security settings the unintended objects will not be accessible and their destructors and other methods will not be called. 
Line 40: Line 42:
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
  
-Since the current patch preserves the binary API, the change can be merged into any PHP version.+Proposed for inclusion into PHP 5.6.x or PHP 7 branches.
 ===== Other issues ==== ===== Other issues ====
  
   * It is not planned that unserialize_callback_func function will be called on prohibited classes as it is done on non-existing classes.    * It is not planned that unserialize_callback_func function will be called on prohibited classes as it is done on non-existing classes. 
-  * This option is not available currently for sessions and any other functions that use unserialization without calling unserialize(). This may be added later if needed. +  * This option is not available currently for sessions and any other functions that use unserialization without calling unserialize(). This may be added later if needed, but for sessions it is very unlikely that untrusted user data will be injected as serialized session data - in that case the problems with security are much larger as pretty much any session-based authentication will be immediately broken 
  
 ===== References ===== ===== References =====
Line 50: Line 52:
    * Unserialize function: http://php.net/unserialize    * Unserialize function: http://php.net/unserialize
    * Example of unserialize() security issue: http://heine.familiedeelstra.com/security/unserialize    * Example of unserialize() security issue: http://heine.familiedeelstra.com/security/unserialize
 +   * Prior discussion: http://grokbase.com/t/php/php-internals/133z8ns916/rfc-more-secure-unserialize
  
 ===== See also ===== ===== See also =====
    * Joomla unserialize() vulnerability: http://seclists.org/bugtraq/2013/Apr/173    * Joomla unserialize() vulnerability: http://seclists.org/bugtraq/2013/Apr/173
    * CubeCart unserialize() vulnerability: http://karmainsecurity.com/KIS-2013-02    * CubeCart unserialize() vulnerability: http://karmainsecurity.com/KIS-2013-02
 +   * TikiWiki unserialize() vulnerability: http://www.securityfocus.com/bid/54298/info
 +   * Invision Power Board unserialize() vulnerability: http://www.securityfocus.com/bid/56288/info
 ===== Changelog ===== ===== Changelog =====
  
   - 2013-03-29 First version published   - 2013-03-29 First version published
rfc/secure_unserialize.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1