Пинговал пользователь запросил хост - это небезопасный код?


<?php
    $userinput = $_GET['host'];
    $e = escapeshellcmd($userinput);
    $arr = (explode(".",$e));
    $num = count($arr);
    $times = (int)$_GET['times'];
    $time = (range(1,51));
    if (!isset($time[$times])){
        $times = 5;
    }
    function isValidURL($url){
        return preg_match('/(www\.)?(.)*[\.](.)*$/i', $url);
    }
    if($num == "2"){
        if(isValidURL($e)){
            echo"<pre style=\"background:black; color:white;\">", passthru("ping -n $times $e"),"</pre>";}
        else {
            echo "The URL or IP $e isn't valid <br />";
    }
?>

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

Я использую взорваться , чтобы знать, если это domain.com или просто текста и регулярное выражение для проверки его не texttext.текст. Есть ли способ для пользователя, чтобы получить доступ к моему терминалу с этим?



394
3
задан 23 сентября 2011 в 09:09 Источник Поделиться
Комментарии
3 ответа

Ваше регулярное выражение для обнаружения действительного URL-адреса является очень слабым, и вы можете скользить много и в прошлом.

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

Два альтернативных атак приходят на ум:


  • Вы можете перегружать свои серверы, делая их отправить кучу ненужных пакетов в пинг-запросов.

  • Вы можете использовать ваш сервер в качестве хоста для нападения на кого-то другого.

Пример отправки дополнительных байтов с пингом (я поставил ваш скрипт в test.php файл на окружения myhost (не настоящее имя).

http://myhost.com/test.php?host=plop.com%20-s%20500

Генерирует:

ping -n 0 plop.com -s 500

4
ответ дан 24 сентября 2011 в 10:09 Источник Поделиться

Я бы сделал $время = мин( (инт) параметр$_GET['время'], 999); где 999-это максимальное количество раз.

2
ответ дан 23 сентября 2011 в 10:09 Источник Поделиться

Следует escapeshellarg или escapeshellcmd быть использованы для хозяина? Я прочел обе страницы только сейчас, и они дают противоречивые советы. Я на 99% уверен, что escapeshellarg должны быть использованы с хозяином, хотя:

$host = shellescapearg("google.com");
exec("ping {$host}");

Как христианин Sciberras начал говорить в своем комментарии:

Я проверить URL-адрес, прежде чем сбежать от него, а не после. Я не могу представить, что бежал бы не когда не бежал бы, нет; однако, когда вы избежать ее, а затем проверить его, вы не проверяя, что было введено, а вы утверждаете обработанный вариант.

Представьте себе такой сценарий: у вас есть профили пользователя, и они позволяют пользователю вводить описание самих. Теперь, они могут иметь некоторые HTML-сущности в них, например, & или <. Теперь, когда вы храните это, вы собираетесь сохранить оригинальную версию. Когда вы покажете его обратно в браузер, вы пройдете через что-то вроде функция htmlentities(). Я считаю, что когда позволяет пользователю обновлять свой профиль, вы собираетесь проверить оригинальную версию с & вместо &.

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

Но и кое-что добавить:

Вы никогда не должны предполагать, что такие ключи существуют в параметр$_GET/$_POST, где/$_COOKIE-файлы, так что на массивах (любой пользователь-зависит от выбора).

Например:

$userinput = $_GET['host'];

Если пользователь просто уходит mypage.php без хозяина парам, то PHP будет выбрасывать уведомление, когда ваш скрипт пытается получить доступ к несуществующему массиву ключ.

Другой случай, когда пользователь может вызвать ошибки что-то вроде:
файла mypage.РНР?узел[]=мля

Это означает, что переменная$_GET['хозяина'] - это массив('бла'). Поэтому, когда вы пытаетесь пройти, что в escapeshellcmd или взорваться, она выдаст ошибку о ожидает строку и получаю массив.

Что я обычно делаю что-то вроде:

if(isset($_GET['blah']) && is_string($_GET['blah'])) {
$blah = $_GET['blah'];
} else {
$blah = null;
}

Или более короткий вариант, который я обычно использую:

$blah = (isset($_GET['blah']) && is_string($_GET['blah'])) ? $_GET['blah'] : null;

Обратите внимание на то, что isset()и не совпадает с array_key_exists, который иногда имеет больше смысла. Кроме того, вы всегда можете использовать is_string , что входные массивы всегда будут содержать строковые значения, даже если пользователь является числовым. (Исключение, если пользователь вводит массив, это становится массивом.)

2
ответ дан 25 сентября 2011 в 10:09 Источник Поделиться