ZF-4600: Allow Select to be serializable

Issue Type: Improvement Created: 2008-10-15T01:48:24.000+0000 Last Updated: 2012-11-20T20:53:24.000+0000 Status: Closed Fix version(s): Reporter: julien PAULI (doctorrock83) Assignee: None Tags: - Zend_Db_Select

Related issues: Attachments: - Zend_Db_Adapter_Abstract.patch


It's not possible actually to serialize a Zend_Db_Select object, as it encapsulates the adapter instance which cannot be serialized.

Selects should be serilizable as this could use caching queries creation.

I'm working on a patch that acts the same way as Zend_Db_Table_Row : it uses __sleep() to disconnect the select object from the DB. __ wakeup() is used with the registry to look for a Zend_Db_Adapter instance into it to assign it back to the Select object. Additionnaly, a setAdapter() method is also provided.


Posted by julien PAULI (doctorrock83) on 2008-10-15T08:46:38.000+0000

Attached a patch that shows how it could work.

Work to do : search for all $this->_adapter calls and throw an exception if not in connected mode.

Posted by julien PAULI (doctorrock83) on 2008-10-22T10:45:36.000+0000

After talking together with Ralph, here is a patch that is backported to the adapter. The select object then keeps its adapter, that's the adapter which drops its connection object.

Simple managing options are also available, methods would follow and those options should get merged with constructor config optionnal options. protected $_allowSerialization protected $_autoReconnectOnUnserialize

Posted by julien PAULI (doctorrock83) on 2008-11-10T08:46:55.000+0000

Use Cases :

<pre class="highlight">
// default behavior
$options = array();

$params = array(
    'host'           => 'somehost',
    'username'       => 'my-name',
    'password'       => 'secret',
    'dbname'         => 'dbname',
    'options'        => $options

$db = Zend_Db::factory('Mysqli', $params);
$_SESSION['dbInstance'] = $db;
// ...later, on another page...
$_SESSION['dbInstance']->fetchAll(); // OK

<pre class="highlight">
// disallow serialization
$options = array(Zend_Db::ALLOW_SERIALIZATION => false);
$params = array(//.......);
$db = Zend_Db::factory('Mysqli', $params);
$_SESSION['dbInstance'] = $db; // exception

<pre class="highlight">
// allow serialization, but do not reconnect SGBD on unserialization
$options = array(Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE => false);
$params = array(//.......);
$db = Zend_Db::factory('Mysqli', $params);
$_SESSION['dbInstance'] = $db; // OK
// ...later, on another page...
$_SESSION['dbInstance']->fetchAll(); // exception

Posted by julien PAULI (doctorrock83) on 2008-12-10T10:37:48.000+0000

r13136 allows Adapter object to be serialized

Posted by Bill Karwin (bkarwin) on 2009-08-17T12:28:52.000+0000

Allowing database adapters to be serialized is a security risk, because the username & password are part of the object data in plain text. If you aren't careful where you store the serialized object, you could expose these credentials.

This is why the serialization of Zend_Db_Table_Row does not serialize the Adapter object. The developer is required to establish the connection in a secure manner before a Row object can be used "live" again.

Posted by Ralph Schindler (ralph) on 2009-08-17T13:02:49.000+0000

Zend_Db_Table_Row has the added benefit of being able to use the static Zend_Db_Table_Adatper::$_defaultDbAdapter, which allows the object to be serialized and unserialized without being injected to.

I am still chewing on this as well as roping others into the discussion. In general, if people are taking care of their security concerns as the Zend_Session layer, then presumably the username/password in the serialization container is as safe as it is inside the ini file it originated from.

More comments to come I am sure. :)

Posted by Ralph Schindler (ralph) on 2009-08-17T13:22:42.000+0000


The original patch suggested that it would consult the registry and also Zend_Db_Table_Abstract::getDefaultAdatper() before (i think) attempting to write to the session, was that the case? I did not see this inside Zend_Db_Select (didnt see any code for sleep and wakeup).


Posted by julien PAULI (doctorrock83) on 2009-08-18T00:20:21.000+0000

The final patch doesn't include any serialization paradigm to the select object, but does to the adapter object. See my comment on 22/Oct/08 10:45 AM and…

Posted by Ralph Schindler (ralph) on 2009-08-18T09:44:44.000+0000

What was the reasoning behind not including serialization to the select object? It seems like if the patch above were applied, it would (in most cases), not need the Zend_Db_Adapter to be serialized as well, right?

Posted by julien PAULI (doctorrock83) on 2009-08-18T11:42:07.000+0000

I dont remember the reason why we did not patch Select but Adapter instead. Affirmative : serializing the Select object would then not need the Adapter to be serialized, just detached.

Posted by Ralph Schindler (ralph) on 2009-08-18T14:11:24.000+0000

I think we should probably include the bits of the original patch so that in most cases, the adapter and its credentials dont make their way into an insecure cache. While I think this is probably an edge case, we should at least do our best to provide a solution for this potential information leak.

I am reopening.

Posted by Rob Allen (rob) on 2012-11-20T20:53:24.000+0000

Bulk change of all issues last updated before 1st January 2010 as "Won't Fix".

Feel free to re-open and provide a patch if you want to fix this issue.

Have you found an issue?

See the Overview section for more details.


© 2006-2018 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.