php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #39118 Private members accessible to print_r
Submitted: 2006-10-10 16:11 UTC Modified: 2011-05-29 08:51 UTC
From: steve at mountainmedia dot com Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5.1.6 OS: Fedora Core 4/Linux 2.6.14.3
Private report: No CVE-ID: None
 [2006-10-10 16:11 UTC] steve at mountainmedia dot com
Description:
------------
Private variables are accessible to the print_r function outside of the object.  Even if one cannot access the variable directly, one could easily parse the output of print_r to grab private data from an object.

Reproduce code:
---------------
<?

class Example {
        private $secret = "My secret";
        public $notsecret = "Not my secret";
}
$ex = new Example;
$x = print_r ($ex, true);
print $x;


?>

Expected result:
----------------
I expected the private members to be invisible or replaced with something to indicate the lack of access such as <Private>.

Actual result:
--------------
Example Object
(
    [secret:private] => My secret
    [notsecret] => Not my secret
)


Private variables are displayed and data is stored in the string variable $x which one could easily parse to get the value of secret:private.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-10-10 16:22 UTC] tony2001@php.net
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


 [2006-10-10 16:40 UTC] steve at mountainmedia dot com
"The visibility of a property or method can be defined by prefixing the declaration with the keywords: public, protected or private. Public declared items can be accessed everywhere. Protected limits access to inherited and parent classes (and to the class that defines the item). Private limits visibility only to the class that defines the item."

How do you see this as not a bug considering that last statement in the documentation on Visibility in PHP 5 Classes (see http://us2.php.net/manual/en/language.oop5.visibility.php).

This is either a bug or bad documentation.  In all logic and understanding, the visibility of a private property should be hidden from any functions such as print_r, overriding the purpose of print_r.
 [2006-10-10 18:19 UTC] steve at mountainmedia dot com
"print_r(), var_dump() and var_export() will also show protected and private properties of objects with PHP 5."

Can this behavior be disabled?  A new feature perhaps?
 [2006-10-11 18:56 UTC] helly@php.net
Why don't you simply disable these functions?
 [2011-05-29 08:41 UTC] x at x dot com
Please, this is silly. Private and protected variables should be just that.
 [2011-05-29 08:51 UTC] rasmus@php.net
There are many ways to get at private methods and properties. One of which is 
simply looking at the source code. PHP is not a compiled language. The visibility 
feature is simply a runtime hint, it is not meant in any way to protect the code, 
and debugging functions such as var_dump and print_r are going to show the full 
objects.
 [2012-09-19 09:10 UTC] sup at sags-per-mail dot de
It is possible to prevent the output of sensitive private data by creating an anonymous function, but the object is not serializable anymore.

This should work with PHP 4 >= 4.0.1 and PHP 5 (based on the documentation of the used functions).

code: 
-----
<?php

class Credentials {
    private $_user;
    private $_password;
    
    function __construct($user, $password) {
        $this->_user = $user;
        
        //uses base64 to get sure the string is escaped
        $base64 = base64_encode($password);
        $function = "return base64_decode('" . $base64 .  "');";
        
        $this->_password = create_function("", $function);
    }
    
    public function getUser() {
        return $this->_user;
    }

    public function getPassword() {
        return call_user_func($this->_password);
    }
}

$credentials = new Credentials("theUserName", "thePassKey");

echo "\n\nprint_r:\n";
print_r($credentials);

echo "\n\nvar_dump:\n";
var_dump($credentials);

echo "\n\nvar_export:\n";
var_export($credentials);


output: 
-----


print_r:
Credentials Object
(
    [_user:Credentials:private] => theUserName
    [_password:Credentials:private] => lambda_1
)


var_dump:
object(Credentials)#1 (2) {
  ["_user":"Credentials":private]=>
  string(11) "theUserName"
  ["_password":"Credentials":private]=>
  string(9) "lambda_1"
}


var_export:
Credentials::__set_state(array(
   '_user' => 'theUserName',
   '_password' => '' . "\0" . 'lambda_1',
))
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 09:01:28 2024 UTC