В фреймворке 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
например? Тем более, что (я бы предположил) входные значения так же полезны, что это фактически предотвращает?
Ваш вопрос сам по себе поднимает хороший момент: неясно, с чем именно вы защищены. Но есть некоторые популярные предметы, к которым он может обратиться:
Но, кроме тех, я действительно не могу придумать, почему вы всегда должны были бы защищать с помощью preg_match("/^[a-z0-9:_\/-]+$/i", $str)
.
У меня такое чувство, что они перестраховываются просто потому, что CodeIgniter настолько широко используется, что им нужно защищать от того, что они сами еще не думали ради своих пользователей, которые могут быть менее осведомлены о таких атаках, чем Разработчики CodeIgniter.
Вы часто видите этот мусор в 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 не так хороши, как ускользнуть, но это намного лучше, чем ничего, и учитывая, сколько разработчиков еще недостаточно сложны, чтобы понять, когда и как убежать, я вижу привлекательность для добавления автоматической очистки переменных запроса.
Скажем в консоли, я меняю имя поля формы с name="email"
на name="email\"); DROP TABLE users;
name="email\"); DROP TABLE users;
Это вряд ли будет успешной атакой XSS, но я могу увидеть что-то подобное, наносящее ущерб плохо закодированному PHP. CI, вероятно, просто пытается охватить все свои базы, чтобы они могли претендовать на то, чтобы как можно скорее защитить XSS.
Такой контроль – пустая трата времени. Вы получаете доступ только к ключам, которые вы ожидаете в любом случае, и если по какой-то причине вы перебираете все элементы, вы, скорее всего, избегаете их должным образом за все, что вы собираетесь с ними делать.
Тем не менее, глядя на навыки среднего новичка PHP-программиста (хотя члены этого вида, скорее всего, вообще не используют фреймворк), он имеет какой-то смысл, вы никогда не узнаете, какие неприятные вещи он будет делать с кодом, который может даже убить его кота без такой проверки.
То же самое относится к отклонению сообщений, содержащих, например, «delete from», как меру анти-SQL-инъекции. Он может легко вызвать ложные срабатывания, и если вы, например, используете параметризованные запросы, вы в любом случае будете в безопасности.
Возможно, он пытается предотвратить эту атаку .
Атака работает, используя знания о том, как PHP строит свои хеширующие структуры для создания ключей в $_POST
которые занимают много времени для обработки.
Я подозреваю, что это, вероятно, просто пытается предотвратить более мирские атаки SQL-инъекций.