From:             andrew at trib dot tv
Operating system: Fed
PHP version:      5.3.1
PHP Bug Type:     Output Control
Bug description:  var_export emits erroneous outputs on vars that contain 
recursive references

Description:
------------
My case is one in which var_export is being used to expose private members
of classes present in the context of an error.  So an error occurs, a
custom handler is invoked, and it var_exports any variables in the error
context which are objects, so that developers investigating the problem can
see the values of private vars within these objects at the time the error
occured.  However, doing this:

$str = var_export($object, true);

If $object contains recursive references, var_export not only fails with a
fatal error that cannot be handled or suppressed, but also flushes its
internal output buffer, so if you've set the second argument to true,
wanting the output returned rather than sent to the browser, you're out of
luck, because it's gone.

This is a security issue, because in some situations, a developer may have
implemented var_export on objects with passwords stored within, and expects
to get the object returned in a string.  If the entire content of the
object (up to the recursive reference) is instead output to the browser,
this data is inadvertently exposed.

I'd say that in such situations var_export should trigger an E_WARNING and
return null or false.  Then it can be safely used on objects that do not
contain recursive references without having to know whether they do or not
before you call the function.

I'm aware of previous bugs filed on this issue, notably 17874 and 16074,
so I raise this specifically in relation to te security implications, and
also making the point that it is not possible to detect whether an object
contains *private* recursive references before you take your life in your
hands by throwing it at var_export and crossing your fingers!

Cheers,

Andrew

Reproduce code:
---------------
<?php
class PrivateThing {
  public $publicvar = 'notsecret';
  private $password = 'supersecret';
  private $reftoself;
  function __construct() { $this->reftoself = $this; }
}
$x = new PrivateThing;
$y = @var_export($x, true);
echo "No passwords here!";
?>


Expected result:
----------------
No passwords here!

Actual result:
--------------
PrivateThing::__set_state(array(
   'publicvar' => 'notsecret',
   'password' => 'supersecret',
   'reftoself' =>
  PrivateThing::__set_state(array(
     'publicvar' => 'notsecret',
     'password' => 'supersecret',
     'reftoself' =>
    PrivateThing::__set_state(array(
       'publicvar' => 'notsecret',
       'password' => 'supersecret',
       'reftoself' =>
      PrivateThing::__set_state(array(


-- 
Edit bug report at http://bugs.php.net/?id=50754&edit=1
-- 
Try a snapshot (PHP 5.2):            
http://bugs.php.net/fix.php?id=50754&r=trysnapshot52
Try a snapshot (PHP 5.3):            
http://bugs.php.net/fix.php?id=50754&r=trysnapshot53
Try a snapshot (PHP 6.0):            
http://bugs.php.net/fix.php?id=50754&r=trysnapshot60
Fixed in SVN:                        
http://bugs.php.net/fix.php?id=50754&r=fixed
Fixed in SVN and need be documented: 
http://bugs.php.net/fix.php?id=50754&r=needdocs
Fixed in release:                    
http://bugs.php.net/fix.php?id=50754&r=alreadyfixed
Need backtrace:                      
http://bugs.php.net/fix.php?id=50754&r=needtrace
Need Reproduce Script:               
http://bugs.php.net/fix.php?id=50754&r=needscript
Try newer version:                   
http://bugs.php.net/fix.php?id=50754&r=oldversion
Not developer issue:                 
http://bugs.php.net/fix.php?id=50754&r=support
Expected behavior:                   
http://bugs.php.net/fix.php?id=50754&r=notwrong
Not enough info:                     
http://bugs.php.net/fix.php?id=50754&r=notenoughinfo
Submitted twice:                     
http://bugs.php.net/fix.php?id=50754&r=submittedtwice
register_globals:                    
http://bugs.php.net/fix.php?id=50754&r=globals
PHP 4 support discontinued:          http://bugs.php.net/fix.php?id=50754&r=php4
Daylight Savings:                    http://bugs.php.net/fix.php?id=50754&r=dst
IIS Stability:                       
http://bugs.php.net/fix.php?id=50754&r=isapi
Install GNU Sed:                     
http://bugs.php.net/fix.php?id=50754&r=gnused
Floating point limitations:          
http://bugs.php.net/fix.php?id=50754&r=float
No Zend Extensions:                  
http://bugs.php.net/fix.php?id=50754&r=nozend
MySQL Configuration Error:           
http://bugs.php.net/fix.php?id=50754&r=mysqlcfg

Reply via email to