Подтвердить что ты не робот

Как ключи ввода могут использоваться злоумышленниками?

В фреймворке CodeIgniter существует функция, которая автоматически запускается для каждого запроса, который, между прочим, фильтрует ключи массива GET/POST/COOKIE и убивает приложение, если он встречает символы, которые он считает небезопасными.

Чтобы злоумышленники не пытались использовать ключи, мы убеждаемся, что ключи называются только с буквенно-цифровым текстом и несколькими другими элементами.

Что-то вроде:

// foreach GET/POST/COOKIE keys as $str...
if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
{
    exit('Disallowed Key Characters.');
}

Например, это будет срабатывать, если вы случайно разместите что-то вроде <input name="TE$T"> или получите строку запроса, например ?name|first=1.

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

4b9b3361

Ответ 1

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

  • магические кавычки
  • вещи, которые в конечном итоге могут привести к SQL-инъекции
  • которые могут быть выполнены с помощью команд оболочки
  • вещи, которые могут конфликтовать с вашим URL.
  • вещи, которые могут противоречить HTML
  • вещи, которые напоминают атаку обхода каталога
  • межсайтовый скриптинг (XSS).

Но, кроме тех, я действительно не могу придумать, почему вы всегда должны были бы защищать с помощью preg_match("/^[a-z0-9:_\/-]+$/i", $str).

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

Ответ 2

Вы часто видите этот нежелательный код в коде noob:

$_SESSION = $_POST;

Известный секрет заключается в том, что $_SESSION является "специальным" и не может обрабатывать символ канала, |, так как ключ верхнего уровня. php не сохраняет переменные сеанса во время shutdown/session_write_close, вместо этого уничтожая весь массив.

session_start();

if (!isset($_SESSION['cnt'])) {
    $_SESSION['cnt'] = 0;
}

$_SESSION['cnt']++;

/* prior to php 5.4, it will never increment, because it never successfuly saves
unless you comment line below
*/
$_SESSION['a|b'] = 1;

print_r($_SESSION);

Я не говорю, что CodeIgniter сглаживает ключи, но это один из многих "способов ввода ключей".

Возможно, более вероятная причина заключается в том, что люди, безусловно, делают такие вещи:

if ($formPostDidntValidate) {
    echo "Please fix the form submission errors and try again\n";
    foreach ($_POST as $key => $value) {
        echo "<p>$key<br>
              <input name='$key' value='$value'></p>";
    }
}

Вывод переменных запроса без соответствующего контекстного экранирования, такого как экранирование для контекстов html, контекстов атрибутов html или даже контекстов sql:

$sql = "select * from myTable where 1=1";
foreach ($_POST as $key => $value) {
    $sql .= " and $key = '$value'";
}

Я видел, как многие люди избегают значения, но не ключ при создании sql и/или html.

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

Ответ 3

Скажем в консоли, я изменяю имя поля формы от name="email" до name="email\"); DROP TABLE users;

Это вряд ли будет успешной атакой XSS, но я могу увидеть что-то подобное, наносящее ущерб плохо закодированному PHP. CI, вероятно, просто пытается охватить все свои базы, чтобы они могли претендовать на то, чтобы как можно скорее защитить XSS.

Ответ 4

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

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

То же самое относится к отклонению сообщений, содержащих, например, "удалить из" в качестве меры по борьбе с SQL-инъекцией. Это может легко вызвать ложные срабатывания, и если вы, например, используйте параметризованные запросы, в любом случае вы в безопасности.

Ответ 5

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

Атака работает, используя знания о том, как PHP строит свои хэш-структуры для создания ключей в $_POST, которые занимают произвольно длительное время для обработки.

Я подозреваю, что это, вероятно, просто пытается предотвратить более мирские атаки SQL-инъекций.