PHP - динамические имена переменных в чем проблема безопасности?

PHP - динамические имена переменных в чем проблема безопасности?

PHP - динамические имена переменных в чем проблема безопасности?

В рамках данной статьи я рассмотрю одну из проблем безопасности, а именно дыру при некорректном коде с динамическими именами переменных.

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

Чтобы не мучить вас теорией, которую далеко не все любят читать, рассмотрим проблему на одном из примеров.

Практически каждому приходится задумываться над системой инициализации переменных из $_GET и $_POST. Если таких переменных несколько штук, то особых проблем не возникает функции isset вполне достаточно. Однако, когда переменных десятки и в зависимости от страниц еще и разные, то у многих возникает вполне естественное ленивое желание как-то автоматизировать этот процесс.

В связи с этим, нередко можно встретить конструкции по типу:

<?php
foreach ($_GET as $key => $value)
{
     // $$key позволяет динамически создавать переменные - очень удобно.
     $$key = $value;
}

Если ужать конструкцию до одной строки, то вообще круто получается. Однако, всегда есть какое-либо "но".

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

<?php
// Часто используемые переменные для отображения статуса админа
$is_admin = 0;
$admin = 0;
$isAdmin = 0;
// Формирование переменных
foreach ($_GET as $key => $value)
{
     // $$key позволяет динамически создавать переменные - очень удобно.
     $$key = $value;
}
// Выведем значения переменных
echo 'is_admin = ' .  $is_admin;
echo '<br/>';
echo 'admin = ' .  $admin;
echo '<br/>';
echo 'isAdmin = ' .  $isAdmin;
echo '<br/>';

Теперь, если сохранить этот код, скажем, в файл test.php и открыть его в браузере без параметров, то вы увидите, что все переменные админки имеют значение 0.

А теперь если открыть следующего вида ссылку:

test.php/?is_admin=1&admin=1&isAdmin=1

То, браузер вам отобразит наглядную проблему с дырой в безопасности при использовании динамических имен переменных. Все значения статуса админки будут иметь значение 1.

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

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

Или же использование stdClass с присвоением в виде:

<?php
$params=new stdClass();
// Формирование переменных
foreach ($_GET as $key => $value)
{
     // Теперь, остальные переменные не будут переписаны
     $params->$key = $value;
}

Как видите, в этой ситуации все переменные создаются внутри объекта stdClass, что решает проблему перезаписи значений.

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

Социальные сети

☕ Понравился обзор? Поделитесь с друзьями!

Комментарии / отзывы  

+1 # DjBobo 08.05.2017 23:04
Начинался про удобство таких конструкций. Думал буду использовать, но прочитал статью и... Люблю статьи, где вполне простые, но доходчивые примеры.
Ответить | Ответить с цитатой | Цитировать | Сообщить модератору
Добавить комментарий / отзыв
Комментарий - это вежливое и наполненное смыслом сообщение (правила).



* Нажимая на кнопку "Отправить", Вы соглашаетесь с политикой конфиденциальности.
Социальные сети
Программы (Freeware, OpenSource...)