ID: 50754
User updated by: andrew at trib dot tv
Reported By: andrew at trib dot tv
Status: Bogus
Bug Type: Output Control
-Operating System: Fed
+Operating System: Fedora
PHP Version: 5.3.1
New Comment:
Incidentally, I'm aware that removing the @ reveals a fatal error - in
fact I said so in my OP. For the sake of absolute clarity, this is what
you get without the @ (and with display_errors enabled):
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(
Fatal error: Nesting level too deep - recursive dependency? in
/root/test.php on line 9
So you still get the spurious output, prior to the fatal error. I'm
not objecting to a recursive input triggering an error, but it should
ideally not be fatal, and most importantly it surely shouldn't cause a
half-complete serialisation to be sent to the browser when you don't
expect this function to produce any output at all.
Previous Comments:
------------------------------------------------------------------------
[2010-01-15 08:29:09] andrew at trib dot tv
Derek,
Thank you for taking the time to select a canned response, though it
would be much more encouraging to bug reporters if you actually
responded to the points made (at length and in the correct manner) in
the bug report before dismissing it as bogus.
Could you comment on why this is not a security vulnerability? The
security implications were initally raised *eight years ago* in bug
17874 by icecube at fr dot fm, but there has been no followup, hence my
fresh bug report.
If serialize($GLOBALS) manages to finish without crashing PHP and
sending a half-complete invalid and potentially sensitive serialisation
string to the browser / console, I don't understand why var_export can't
do the same, nor what the justification is for claiming that the current
behaviour is desirable.
Cheers,
Andrew
------------------------------------------------------------------------
[2010-01-14 22:00:57] [email protected]
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
Remove the @ and you see what really happens:
Fatal error: Nesting level too deep - recursive dependency? in - on
line 9
------------------------------------------------------------------------
[2010-01-14 16:52:57] andrew at trib dot tv
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 this bug report at http://bugs.php.net/?id=50754&edit=1