Доброе время суток Столкнулся с проблемой, ответ на который не смог найти на просторах интернета. Сразу к делу. Поставили передо мной задачу написать непрозрачный объектно-ориентированный код на php. Есть система, которая работает с некоторыми секретными данными. Данные хранятся в xml, и закрыты ассиметричным ключом. Закрытый ключ хранится в коде внутри финализированного метода внутри класса. Класс накрыт зендом и поднимается только через дизасм. Скрепя сердце начальство признало этот способ безопасным. Доступ к классу осуществляется через https соединение. Столкнулся с проблемой, которая разорвала мне мозги: вся эта система ходит по рукам, но всё время остается закрытой для сторонних разработчиков за исключением того, что у системы есть документированное API. А значит на эту систему вешаются сторонние модули. Не смотря на то, что сам класс, который парсит xml с секретными данными финализированный и всё, что можно находится в private, добрые люди намекнули, что эта система пробиваема на Ура. Способ обхода очень странный: самый верхний объект прогоняется через var_dump, результат вывода кэшируется, а затем кэш парсится. Получается, что если мой объект расшифровал секретный xml, то он хранит распарсированные конфиги у себя в private свойствах, потом его сканирует сторонний модуль через var_dump или print_r и грабит секретную статическую информацию производителя системы, которая одинакова на всех копиях системы. На сколько мне известно, var_dump и print_r могут получить доступ к всем свойствам (в том числе private и protected). Уязвимостью это язык не поворачивается, это дыра, в которую можно пешком пройти. Пока что для себя нашёл только один способ, как можно хранить хоть сколько-нибудь непрозрачную информацию - использовать константную строку в теле финализированного private метода. Но это подходит только для статики. Есть еще одна область, которая меня тревожит - это СlassKit. Вплотную с ним не работал, но на сколько я знаю, он позволяет копировать чужие методы из других классов в свой. Получается, что нужно привязываться к имени класса, но и эту проблему злоумышленник сможет обойти. Прошу помощи у сообщества. 1) Проконсультируйте на счёт возможностей ClassKit. Так ли всё ужасно? 2) Что делать с var_dump? 3) Как вообще бы вы решали проблему такого рода? Если я не очень понятно объяснил суть проблемы, спрашивайте - я всё что можно рассказать расскажу и покажу.
я не понял смысла, почему для API отдается объект? парсит пусть сервак, а клиентский код только получает ограниченную инфу в свой объект так на пример /api/getsomething/1/ или я что то не так понял?
система купле-продажная. т.е. клиент покупает у нас код, который накрыт зендом и дописывает модули под свои нужды. клиент и сторонний разработчик для нас - это один и тот же человек. у нас задача защитить секретные данные, которые хранятся внутри файлов конфигурации, от других разработчиков. если я пишу API, то получается, что мой код и код стороннего разработчика исполняется параллельно. мой объект имеет открытые методы, через которые он взаимодействует с чужими объектами. напрямую сторонний код не может распарсить мои файлы конфигурации, потому что он не знает мой закрытый ключ (который хранится в финализированном private методе моего класса в виде константы). но если я уже распарсил конфиг и передаю управление чужому модулю, то чужой модуль может через var_dump распотрошить меня и получить секретную информацию. вот в этом и проблема
titch может глупая идея, но, как насчет того чтобы сделать методы статическими, запретить создание и клонирование объекта? к слову, расшифруют все равно, если захотят
это вопрос времени, не спорю. м... если можно, пример в студию. упрощенно текущая схема: PHP: class c_Center { private $DOM_Secret; final private function f_Key () { return "1234567890"; //очень упрощенно } final private function f_ParseSecret() { //открываем при помощи f_Key конфиг, парсим его и записываем в $this->DOM_Secret } public function f_MakeProfit($input) { //используя $this->DOM_Secret и $input приносим пользу другому классу } } $center = new c_Center(); $charlie->cash_var_dump($center); //получаем доступ извне к $DOM_Secret получается, что не имеет значения, кто создает объект center. еще хуже, если ClassKit дает возможность сразу скопировать $center->f_Key() в чужой класс как видно, такой подход к f_Key не дает сразу получить доступ к ключу. если записать ключ как private $key, то он вынимается через тот же самый $charlie->cash_var_dump($center); функция хотя бы не вскрывается так просто. но значение там статично. а файлы конфигурации для того и нужны, чтобы через какое-то время можно было без внедрения в код обновить ключи протекции
PHP: <?php final class Center { private static $domSecret = 'DOM'; public function makeProfit($a){ return self::$domSecret.$a; } public function __construct(){ exit("error"); } } echo Center::makeProfit('::Profit'); //а тут хрен $c = new Center();
выше всяких похвал!) посмотрел со всех сторон, вроде пока не придумал способ пробить. спасибо! если всё же что-то появится, то буду писать в эту же тему.
titch насчет класс кита http://www.php.net/manual/en/function.c ... import.php он похоже просто парсит файл, если все зашифровано то ничего не получится, проще проверить, а расшифровать точно расшифруют, если приспичит
класскит больше пугает не своим импортом, сколько вот этим методом: http://www.php.net/manual/en/function.c ... d-copy.php попробовать в самое ближайшее время не смогу, но если руки дойдут, то проверю его на прочность upd: кроме прочего прошу заметить, что уязвимость в нестатических классах осталась
безобъектные классы - палка о двух концах. нет объекта - нельзя зарегистрировать как переменную сессии. а значит, что при переходе со страницы на страницу, класс Center нужно перестраивать заново даже для одного и того же пользователя (и конфиг парсить заново). операция вместе с расшифровыванием дорогостоящая по ресурсам (хотя там в моем контексте хранить в сессии секретную инфу вообще нельзя). не торт. но в моём случае это оправдано.
а чего так сложно? класс, который наследуется от вашего, не сможет переопределить private-метод, потому что он private. мне для общего развития: можете показать "var_dump верхнего объекта, доступ к классу которого осуществляется через https соединение"?
Найстройки сервера позволяют передавать php-файлы через https соединение, а не только исполнять их. var_dump производится уже по созданному объекту на стороне сервера нашего клиента. Прошу еще заметить, что сам php код не открыт, а скомпилирован под zend.
titch Решили задачку? А почему бы например не хранить сами секретные данные зашифрованными? И сделать зазенденый декодер? т.е. нам придётся уже скрывать только алгоритм, что вроде легче, нет?
А разве сериалайзом не пробивается?))) Магия вам в помощь)) ПС Пробивать сериалайзом не пробовал тк на текущей оси серв не стоит)
На сколько я знаю, сериализация не может быть применена к классу. А здесь как раз тот случай, когда объекта класса не существует. На счет хранения в сессии секретных значений тоже проблема решилась достаточно банально - используется MCrypt, и написана система для управления переменными, которые нужно хранить в сессиях зашифрованными. Решил, что лучше один раз разделаться с этим вопросом, и больше никогда к этому не возвращаться. Кстати, сама эта система работает на принципе, описанном сколько-то постов выше. Еще раз спасибо, всё работает идеально. ps: пробоем var_dump уже сам воспользовался несколько раз в практических целях и даже извлек из этого некоторую коммерческую выгоду, что и вам рекомендую )) Категорически не советую вам использовать криптографические методы, устойчивость которых зависит от сокрытия алгоритма. Сегодня ваша методика работает, а завтра дизасмом вас на части раскрошат. И если использовать шифрование для каждой переменной, получается слоупок-код. А я не люблю медленный код :Р
PHP: <?php $r = new ReflectionClass('Center'); print_r($r->getStaticProperties()); Правда вроде как зенд требует отключенного reflection, но вообще-то зенд ломается на ура, уж лучше ионкуб.
проверил, реально пробивает. какие есть варианты, как проверить, чтобы reflection был отключен прямо в скрипте?
в том-то и проблема.. если бы у него был какой-либо идентификатор хитро-хитрый... или есть еще какой-либо обходной вариант? жэсть... дырявый php... ой, дырявый... ps: есть у меня предположение, что ионкуб вскроется точно также - через модуль перехвата кода в php. есть мысли на этот счёт?