Jump to content
  • 0

Что не так в этом коде PHP


Jey Val Star
 Share

Question

Здравствуйте.

Есть участок кода определяющий какой язык выбрал пользователь

// определения языка сайтаif($_GET['lang']){    if(file_exists('languages/' . $_GET['lang'] . '.php'))    {        $lang_file = $_GET['lang'] . '.php';        $lang_link = '?lang=' . $_GET['lang'];    }}include 'languages/' . $lang_file; //подключение языкового файла

Такой ответ от программиста

 

 

Даете почти прямой доступ к файловой системе сервера (engine/engine.php:13 и :19)

Вопрос - как правильно выполнить этот код?

Link to comment
Share on other sites

22 answers to this question

Recommended Posts

  • 0

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

по большому счету, настройки прав на сервере вполне хватит для предотвращения прямого доступа к файловой системе.

Link to comment
Share on other sites

  • 0

Может тут имелось в виду указание пути через переменную (константу)?

define('LANG','languages');// определения языка сайтаif($_GET['lang']){    if(file_exists(LANG . $_GET['lang'] . '.php'))    {        $lang_file = $_GET['lang'] . '.php';        $lang_link = '?lang=' . $_GET['lang'];    }}include LANG . $lang_file; //подключение языкового файла
Link to comment
Share on other sites

  • 0

Ну тут наверное имелось в виду что в $_GET['lang'] может всякое приходить. Как вариант можно получить массив файлов директории, и проверять на наличие $_GET['lang'] в этом массиве и если такое существует то инклудить файл.

Но как сказал rus опасности в этом коде нет, и намного правильнее настраивать права на сервере.

  • Like 1
Link to comment
Share on other sites

  • 0

Потому что в $_GET['lang'] можно послать любое имя файла, и при определенном навыке получить полный контроль над сайтом и базой данных.

Первое, на что проверяют сайт при взломе - это защищенность $_GET параметров, а также возможность провести SQL инъекции через них.

Edited by Radiocity
Link to comment
Share on other sites

  • 0

Вспоминая первые шаги - любому новичку должна попадаться статья на офф сайте пыхи, на форуме пхпклаб и т.п. Это просто классический пример инклюдинга - его суют везде куда не лень. Вопрос, что вы не можете знать на каком сервере будет выполняться код и программист прав. Кроме того, этот код неправилен от и до. Сборка пути разбросана по коду, если нужно будет изменить путь - придеться лезть в логику. есть дубирование кода - $_GET['lang'] . '.php' выполняется два раза! и вообще - 4 (!) раза обращение к $_GET['lang'] - кроме дубрилования, т.к. 'lang' это строка не исключено, что при изменении придется искать и заменять и если в коде будет переменная $lang, то без регекспов появится сюрприз.

Кроме того, что будет с переменной $lang_file если if не сработает. Или это подразумевался сокращенный вариант if и переменная уже инициализирована где-то в коде по дефолту, или это просто недочет и там ничего не будет, но будет ошибка.

rus вам скинул ссылку- там ключевой момент - изменение пользователем содержимого массивов пост или гет для изменения пути подключаемого файла!

Link to comment
Share on other sites

  • 0

Вспоминая первые шаги - любому новичку должна попадаться статья на офф сайте пыхи, на форуме пхпклаб и т.п. Это просто классический пример инклюдинга - его суют везде куда не лень. Вопрос, что вы не можете знать на каком сервере будет выполняться код и программист прав. Кроме того, этот код неправилен от и до. Сборка пути разбросана по коду, если нужно будет изменить путь - придеться лезть в логику. есть дубирование кода - $_GET['lang'] . '.php' выполняется два раза! и вообще - 4 (!) раза обращение к $_GET['lang'] - кроме дубрилования, т.к. 'lang' это строка не исключено, что при изменении придется искать и заменять и если в коде будет переменная $lang, то без регекспов появится сюрприз.

Кроме того, что будет с переменной $lang_file если if не сработает. Или это подразумевался сокращенный вариант if и переменная уже инициализирована где-то в коде по дефолту, или это просто недочет и там ничего не будет, но будет ошибка.

rus вам скинул ссылку- там ключевой момент - изменение пользователем содержимого массивов пост или гет для изменения пути подключаемого файла!

Если я правильно вас понял то $_GET['lang'] (если существует) нужно проверить на допустимость при этом перевести в переменную. А потом использовать эту переменную для includ. И следующий момент - все пути прописать в конфиге (к примеру в виде констант) и для подключения файлов использовать эти константы?

что будет с переменной $lang_file если if не сработает

Эта переменная определена выше. В этом участке просто переопределяется значение (если есть).
Link to comment
Share on other sites

  • 0

Я соглашусь с программистом.
Предположим у вас в корне есть файл password.php (этот файл не обязательно может хранить пароли и называться так), но

я передаю $_GET['lang'] = "/../password" и вуаля, мы видим то, чего не должны были, ну или хотя бы можем определить наличие интересующего нас файла.

а если я сделаю такое $_GET['lang'] = "/../password.ini?" тут я вообще любой файлик могу получить

1. совет, который обычно всегда дают - это проверять все входящие данные и даже куки

2. я бы посоветовал вам использовать свою функцию include в которой бы проводилась проверка прав доступа к файлу (если у вас существует система прав доступа к файлам)

Link to comment
Share on other sites

  • 0

Переделал код - так лучше?

// определения языка сайтаif(isset($_GET['lang'])){    $key = array_search($_GET['lang'], $lang_file_arr); // проверка допустимых значений в GET    $lang_file = $lang_file_arr[$key]. '.php'; // для подключеия файла    $lang_link = '?lang=' . $lang_file_arr[$key]; // установка языка для ссылок}include PATH_LANG . $lang_file; //подключение языкового файла

PS опробовал передать в GET вызов другого файла (../index.php) вышло сообщение о ошибке "Прекращена работа программы Apache ...". Теперь не выводит)))

Edited by Jey Val Star
Link to comment
Share on other sites

  • 0

ну, ронять своим кодом apache это не есть гут =)

 

мой многословный вариант реализации:

http://pastebin.com/yfkgLFzw

не запускал, так что это не рабочий пример, скорее в качестве демонстрации ООП подхода. Можно выделить интерфейс ( ::inludeLanguage($code) ) и кроме файловой реализации запилить любую другую совместимую.

Link to comment
Share on other sites

  • 0
Но все таки что это значит?

Вот Вам пример урла, который может быть передан от пользователя:

http://host.com/request?lang=../../../script/scripthttp://host.com/request?lang=../../../lib/scripthttp://host.com/request?lang=../../site/download/my_file

Таким образом Вашь скрипт позволит "лазить" по всем доступным закаулкам ФС, которые доступны пользователю от имени которого исполняется скрипт. От Вас хотят исключить возможность вставки спец символов(".","..","/"), которые позволят выйти за пределы папки где лежат языковые скрипты.

Edited by CoDy
Link to comment
Share on other sites

  • 0

Вставлю и я своих 5 копеек.

Я бы реализовал примерно так:

<?if ($_GET["LANG"]) {    $lang = htmlspecialchars($_GET["LANG"]);    $lang_array = array(); //массив со всеми возможными языками    $get_me_lang = array_search($lang, $lang_array);    if ($lang_array[$get_me_lang]) {        include 'languages/' . $lang_array[$get_me_lang];    }    else {        echo '<pre>'; print_r("ХАКИРШТОЛЕ?"); echo '</pre>';    }}?>
Link to comment
Share on other sites

  • 0

 

    $get_me_lang = array_search($lang, $lang_array);    if ($lang_array[$get_me_lang]) {
А где обработка случая, когда $get_me_lang === false?

 

может чего-то я не понимаю, но я же написал else. Не могли бы объяснить. Спасибо

Link to comment
Share on other sites

  • 0

может чего-то я не понимаю, но я же написал else. Не могли бы объяснить. Спасибо

1) В php 0 == '' == false == '0' == null.

2) Функция array_search ищет вхождение элемента в массив и возвращает его индекс.

3) Индекс может оказаться нулевым, это допустимое значение, насколько я понимаю

4) В случае, если элемент вообще не найден, то возвращается не ноль, а false, поэтому для if нужно строгое сравнение if ($lang_array[$get_me_lang] !== false) {} else {}, иначе получается, что в else уходит даже допустимое значение 0.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy