Защищает ли эта функция PHP от внедрения SQL? - PullRequest
2 голосов
/ 31 марта 2010

У меня есть эта функция, которую я использую, и я хочу быть уверен, что она полностью защищает от атак SQL-инъекций:

function MakeSafeForQuery($string)
{
    // replace all of the quote
    // chars by their escape sequence

    $ret = str_replace("\\","\\\\",$string);
    $ret = str_replace("'","\\'",$ret);
    $ret = str_replace("\"","\\\"",$ret);

    return $ret;
}

Я что-то упустил?

Редактировать: Кстати, я использую MySQL.

Ответы [ 5 ]

10 голосов
/ 31 марта 2010

В GBK 0xbf27 не является допустимым многобайтовым символом, но 0xbf5c. Интерпретируется как однобайтовые символы, 0xbf27 - это 0xbf (¿), за которым следует 0x27 ('), а 0xbf5c - это 0xbf (¿), за которым следует 0x5c (\).

Как это помогает? Если я хочу предпринять атаку SQL-инъекцией на базу данных MySQL, экранирование одинарных кавычек с обратной косой чертой - облом. Однако если вы используете addslashes(), мне повезло. Все, что мне нужно сделать, это ввести что-то вроде 0xbf27, и addslashes() изменит это, чтобы оно стало 0xbf5c27, допустимым многобайтовым символом, за которым следует одиночная кавычка. Другими словами, я могу успешно ввести одну кавычку, несмотря на ваше побег. Это потому, что 0xbf5c интерпретируется как один символ, а не два. Упс, идет обратный слеш.

Этот тип атаки возможен с любой кодировкой символов, где существует допустимый многобайтовый символ, заканчивающийся на 0x5c, потому что addslashes() может быть обманным путем, чтобы создать действительный многобайтовый символ вместо экранирования следующей кавычки , UTF-8 не подходит под это описание.

Чтобы избежать этого типа уязвимости, используйте mysql_real_escape_string()

http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

3 голосов
/ 31 марта 2010

В наши дни вы должны использовать подготовленные операторы , параметры которых не уязвимы для инъекций, а не дезинфицировать функции. PDO поддерживает их.Прочитайте « Написание сценариев MySQL с PHP и PDO » для получения дополнительной информации.

Обратите внимание, что в большинстве драйверов БД можно параметризовать только скалярные значения.Сложные значения (например, используемые в операторе IN (<em>list</em>)) и другие части операторов обычно не могут быть параметризованы.Для этого вам все еще нужно интерполировать значения в операторе.Лучше никогда не использовать пользовательский ввод напрямую для чего-либо, кроме значений.

3 голосов
/ 31 марта 2010

Для защиты от SQL-инъекций не следует использовать функцию, которую вы пишете самостоятельно.

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

Например:


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

1 голос
/ 31 марта 2010

Не могли бы вы просто использовать mysql_real_escape_string или вы пытаетесь сделать это без подключения к базе данных?

(что, кажется, побеждает цель ...)

0 голосов
/ 21 декабря 2011

Определенно НЕТ.

Не из-за каких-то экзотических кодировок, которые вы никогда не встретите в своей жизни, но из-за того простого факта, что побег в одиночку ничего не помогает .

Добавление косых черт не похоже на какое-то божественное вмешательство, которое мгновенно предотвращает страшную инъекцию.

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

Для дальнейших объяснений вы можете обратиться к моему предыдущему ответу на аналогичный вопрос: https://stackoverflow.com/a/8061617/285587

Что касается принятого ответа, просто имейте в виду, что и mysql_real_escape_string (), и подготовленные операторы PDO имеют абсолютно одинаковую уязвимость, если используются сами по себе, без принятия необходимых мер предосторожности. Вы должны правильно установить клиентскую кодировку, чтобы они работали как положено.

Таким образом, на самом деле только use mysql_real_escape_string() поможет вам не более, чем ваша собственная функция.

mysql_set_charset () должен использоваться с mysql_real_escape_string () и в PDO либо режим эмуляции должен быть отключен, либо кодировка должна быть установлена ​​в DSN

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...