Почему частные переменные в объекте "видны" из внешнего мира?


Учитывая этот пример:

class Database
{
    private $host,
            $database, 
            $username, 
            $password,
            $type;

    public $active_connection;

    //Some methods
}


class Page
{
    private $db;


    public function __construct($id)
    {
        // Some code

        $this->db = new Database($id);
    }

    //Some Methods
}


$page = new Page(0);

var_dump($page);

Это выведет частные переменные объекта базы данных, даже если они помечены как частные (и поэтому, как я понимаю, непригодны для использования внешним миром).

Мои вопросы таковы:

  1. Является ли это угрозой безопасности?
  2. Есть ли способ эффективно скрыть эти переменные, помеченные как частные?

Заранее благодарю

РЕДАКТИРОВАТЬ: В этом проекте раздел администратора предоставит возможность создавать пользовательские PHP сценарии для включения в сайт в виде разделов. Поскольку это разрабатывается для сторонней организации, меня беспокоит то, что по какой-то причине заказчик непреднамеренно сбрасывает объект $page (который в нашем коде является основным изменяемым объектом), чтобы "изучить" его.

Author: Tivie, 2011-10-25

7 answers

Var_dump() показывает их, потому что это особенное. Вы также можете покопаться в частных/защищенных свойствах, используя API отражения .

Эхо $объект->_someprivatevar;

С другой стороны, не будет раскрывать _somePrivateVar.

1) Это проблема безопасности? Нисколько. Если вы не доверяете коду, который выполняете, вы в значительной степени обмануты.

2) Скрывать их от чего? Они уже скрыты в соответствии с правилами видимости данных системы классов. Но язык динамичен и предоставляет некоторые другие способы заглянуть внутрь. Как только что сказал Леонид в своем ответе, это архитектурный механизм, а не функция безопасности.

 4
Author: timdev, 2011-10-24 23:25:55

Инкапсуляция - это архитектурный механизм, а не мера безопасности, и ее нельзя использовать как таковую.

Как именно злоумышленник воспользуется этой угрозой безопасности? Он доступен только изнутри исходного кода, поэтому он также может прочитать исходный код вашего защищенного класса или любого другого исходного кода в проекте.

Кроме того, даже в C++ вы можете получить доступ к закрытым элементам, подготовив указатель с правильным смещением в объект.

 6
Author: Leonid Shevtsov, 2011-10-24 23:24:55

Новый волшебный метод __Debuginfo() был введен в PHP 5.6, который позволит вам изменять поведение var_dump() по умолчанию при сбросе ваших объектов.

Ознакомьтесь с документацией .

Пример:

<?php
class C {
    private $prop;

    public function __construct($val) {
        $this->prop = $val;
    }

    public function __debugInfo() {
        return [
            'propSquared' => $this->prop ** 2,
        ];
    }
}

var_dump(new C(42));
?>

Возвращает:

object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}

Хотя этому вопросу уже 3 года, я уверен, что кто-то найдет это полезным в будущем.

 4
Author: Dušan Brejka, 2014-09-23 09:54:26

var_dump предназначен для разработчика для отслеживания и отладки кода. Из документации :

В PHP 5 все публичные, частные и защищенные свойства объектов будут возвращены в выходных данных.

 2
Author: Tom, 2011-10-24 23:24:01

Это задокументированное поведение для var_dump (а также для print_r и var_export). Это предназначено для того, чтобы получить представление о вашем работающем коде; например, при его отладке вы хотели бы знать значение частных переменных.

Вы можете перехватить вывод с помощью функций управления выводом или использовать var_export, если вам нужно использовать содержимое частной переменной в другом классе. Это была бы необычная ситуация: в этом случае вы, скорее всего, все равно использовали бы общедоступную переменную. Если бы вы разрабатывали какой-то набор тестов, который должен был проверять содержимое частных переменных, это был бы ваш ответ.

 1
Author: Mike, 2011-10-24 23:27:34

Я знаю, что это старый вопрос, но я хотел бы указать на (довольно) эффективное средство маскировки переменной;

Вы можете создать функцию внутри класса, в котором хранятся статические переменные; Если у вас есть переменная, которую, по вашему мнению, действительно необходимо скрыть от самой системы, сохраните ее в статической переменной функций. Пока эта функция является частной для класса, заглянуть внутрь становится очень трудно. Это нормально, если по какой-то причине ваш сервер сбрасывает значения на страна пользователей, и вы не можете ее контролировать.

Но, как сказал ТимДев: если вы не доверяете коду, который выполняете, это признак того, что у вас есть более серьезные проблемы с безопасностью. Даже если у вас есть проект на основе плагинов с потенциальными вредоносными авторами pluin, вы просто не сможете защитить себя в этой среде. Это будет зависеть от администратора, который установит эти плагины для обеспечения безопасности.

 1
Author: Kver, 2012-11-07 20:46:46

Выезд __debugInfo() волшебный метод в руководстве по PHP как скрыть конфиденциальные данные из трассировок стека (добавлено в PHP 5.6.0). Вот пример:

class PDO_Database
{
    private $db_user = 'my_user';
    private $db_password = 'my_password';

    /**
     * The purpose of this method is to hide sensitive data from stack traces.
     *
     * @return array
     */
    public function __debugInfo()
    {
        $properties = get_object_vars($this);

        $hidden = [
            'db_user' => '***',
            'db_password' => '***',
        ];

        return $hidden + $properties;
    }
}
 0
Author: Krzysztof Przygoda, 2017-03-27 17:56:21