Уязвимость заключается в том, что можно отправить любой относительный путь в $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
).
person
CherryDT
schedule
19.05.2016
xxx
в полеlang
вашей формы, вы попытаетесь включить несуществующий файл. - person RiggsFolly   schedule 19.05.2016