Почему закрытые переменные в объекте "видны" из внешнего мира? - PullRequest
4 голосов
/ 25 октября 2011

Данный пример:

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. Есть ли способ эффективно скрыть эти переменные, помеченные как закрытые?

заранее спасибо

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

Ответы [ 7 ]

6 голосов
/ 25 октября 2011

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

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

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

4 голосов
/ 23 сентября 2014

Новый магический метод __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 голосов
/ 25 октября 2011

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

echo $ object -> _ somePrivateVar;

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

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

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

2 голосов
/ 25 октября 2011

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

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

1 голос
/ 08 ноября 2012

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

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

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

1 голос
/ 25 октября 2011

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

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

0 голосов
/ 27 марта 2017

Изучите __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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...