Я читаю о безопасности в Интернете, и одна очевидная тема для этого – это инъекции SQL. Я пытаюсь создать базовую php-страницу, где я могу выполнить SQL-инъекцию (ее локальный сервер). Однако, кажется, мой код (или сервер) автоматически ускользает от одиночных кавычек. Это новый стандарт или есть настройки, которые активируются на моем сервере, о которых я не знаю? Есть ли необходимость в очистке ввода больше?
Вот пример моего кода на стороне сервера:
$foo = $_POST['foo']; $sql = "SELECT * FROM bar WHERE foo='".$foo."'"; connectoTo("database"); query($sql);
Где connectTo () подключается к серверу базы данных и выбирает базу данных, а query () – обычная процедура, используемая при выполнении запроса. Не чистите, что так было. Однако, когда я отправляю
$_POST['foo'] = "' OR 1=1 #"
php-страница получает это как
$_POST['foo'] = "\' OR 1=1 #"
Так что foo уже сбежал? То же самое с $ _GET.
Есть предположения? Нам больше не нужно очищать ввод пользователей?
ура
Erik
В PHP есть мертвая функция, которая автоматически удаляет данные POST / GET под названием Magic Quotes . Идея заключалась в том, чтобы избежать распространенных типов SQL-инъекций.
В действительности вы получаете беспорядочные данные, и SQL-инъекция по-прежнему очень возможна, в зависимости от реализации. Разработчики PHP быстро поняли это и отказались от этой функции, и обескуражили ее использование.
В правильной установке PHP это абсолютно необходимо отключить! Если у вас нет доступа к PHP.ini для установки magic_quotes_gpc off
, вы можете поместить это в начало своего кода:
if (get_magic_quotes_gpc()) { $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); while (list($key, $val) = each($process)) { foreach ($val as $k => $v) { unset($process[$key][$k]); if (is_array($v)) { $process[$key][stripslashes($k)] = $v; $process[] = &$process[$key][stripslashes($k)]; } else { $process[$key][stripslashes($k)] = stripslashes($v); } } } unset($process); }
сif (get_magic_quotes_gpc()) { $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); while (list($key, $val) = each($process)) { foreach ($val as $k => $v) { unset($process[$key][$k]); if (is_array($v)) { $process[$key][stripslashes($k)] = $v; $process[] = &$process[$key][stripslashes($k)]; } else { $process[$key][stripslashes($k)] = stripslashes($v); } } } unset($process); }
сif (get_magic_quotes_gpc()) { $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); while (list($key, $val) = each($process)) { foreach ($val as $k => $v) { unset($process[$key][$k]); if (is_array($v)) { $process[$key][stripslashes($k)] = $v; $process[] = &$process[$key][stripslashes($k)]; } else { $process[$key][stripslashes($k)] = stripslashes($v); } } } unset($process); }
Снято с: http://www.php.net/manual/en/security.magicquotes.disabling.php
Теперь, на вашу проблему с SQL-инъекцией. Понимаете, есть гораздо больше проблем, чем просто цитаты. Вы не указываете, какую базу данных вы используете, но это не имеет значения. Лучший способ избежать проблем с инъекциями – использовать подготовленные / параметризованные запросы.
Подготовленные запросы – это запросы, отправленные на сервер с параметрами, значения которых отправляются позже.
INSERT INTO someTable (field1, field2) VALUES (:field1, :field2);
Обратите внимание :field1
и :field2
, поскольку они являются параметрами. Когда я выполню это заявление, они будут заменены соответствующими значениями. Поскольку сервер делает это, не требуется экранирование (и / или это происходит в фоновом режиме для вас, в зависимости от используемого вами уровня БД).
Самый простой способ реализовать это в PHP – это использование PDO. Как использовать PDO слишком длинный для этого окна, поэтому я укажу вам в сторону учебника:
http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
Отключите magic_quote
в php.ini и используйте PDO
.