использование локального включения файла при включении языкового файла

У меня есть php-код для моего сайта, и мой друг сказал мне, что в моем коде есть локальная уязвимость включения файлов, потому что я использую метод «include».

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

вот код ниже, чтобы быть более понятным:

<?php

if(isSet($_GET['lang']))
$lang = $_GET['lang'];
else $lang='en';

include 'languages/'.$lang.'.php';
include("header.php");
?>

P.S у меня есть только 2 языковых файла, и они английские = «en.php» и арабский = «ar.php»

Я был бы очень признателен, если бы кто-то мог помочь.

2

Решение

Никогда не доверяйте пользовательским вводам!

<?php

if ( isset($_GET['lang']) && $_GET['lang'] == 'en') {
$lang = 'en';
} else {
$lang = 'ar';
}

include 'languages/'.$lang.'.php';
include("header.php");

?>

Или, готовясь к возможным дополнительным языкам, я бы пошел так:

<?php

$lang = !empty($_GET['lang']) ? $_GET['lang'] : 'en';

switch($lang) {
default:
case 'en':
include 'languages/en.php';
break;
case 'ar':
include 'languages/ar.php';
break;
}

include("header.php");

?>

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

2

Другие решения

Уязвимость заключается в том, что можно отправить любой относительный путь в $lang, Это особенно опасно, если пользователи могут загружать файлы и определять свой реальный путь на сервере.

Пример:

  • Хакер может использовать некоторые функции загрузки файлов вашего сайта для загрузки evil.php, Хакер может знать / узнал / догадаться, что он хранится в /var/www/uploads/evil.phpи что ваше приложение работает в /var/www/html,
  • Теперь обычно никто не может запустить этот файл, если /var/www/uploads не доступен через HTTP.
  • Но можно было бы открыть http://example.com/index.php?lang=../../uploads/evil и угадайте, что это будет включать languages/../../uploads/evil.php который решил бы /var/www/uploads/evil.php!

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

И если вы сейчас думаете, что «это довольно много предположений, а может и« да », если вам это нужно, вам очень повезет, чтобы преуспеть с этим», тогда будьте осторожны — хотя есть несколько очевидных явных уязвимостей, когда вы делаете один URL позвоните, и вы можете, скажем, обогнать сервер или удалить базу данных, наиболее опасными из них являются те, которые требуют нескольких частей головоломки для работы эксплойта, потому что они остаются незамеченными в течение длительного времени, и может быть трудно понять, как Сервер действительно был взломан, как только это произойдет, и вы, естественно, будете иметь более опытного и, следовательно, более опасного (возможно, невидимого) хакера у вашего порога. Если кто-то полон решимости найти дыру в безопасности (либо потому, что у него есть реальная цель, нападающая на ваш сайт или на вас, либо потому, что ему просто нравится иметь плохих веб-мастеров, чтобы подтолкнуть свое собственное эго), он будет продолжать поиск и ломать голову над тем, что требуется для достижения что они хотят.


Есть несколько решений.

Как предложено u_mulder, если у вас есть только ar а также en тогда просто проверьте, если это один из них.

Если у вас есть больше языков, вы можете просто создать массив со списком допустимых значений и проверить, находится ли отправленный язык в этом массиве, например:

$languages = ['de', 'en', 'ar', 'jp', 'fr'];
if(in_array($_GET['lang'], $languages)) {
$selectedLanguage = $_GET['lang'];
} else {
$selectedLanguage = 'en'; // default
// Note that you could also show an error "invalid language" instead
}

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

if(preg_match("/^[a-z]*$/", $_GET['lang'])) { ... }

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

1

По вопросам рекламы [email protected]