Одиночные кавычки экранируются автоматически в PHP? Тогда зачем нужна уборка?

Я читаю о веб-безопасности, и одной очевидной темой для рассмотрения являются инъекции 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

2 ответа

Решение

В 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);
}

Взято с: 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 in php.ini and use PDO,

Другие вопросы по тегам