Что mysql_real_escape_string() делает, что addlashes() не делает?

Зачем нам нужны специфичные для БД функции, такие как mysql_real_escape_string()? Что он может сделать, чего не делает addlashes()?

На данный момент не обращая внимания на превосходную альтернативу параметризованных запросов, является ли веб-приложение, которое использует addlashes(), все еще уязвимым для SQL-инъекций, и если да, то как?

12 ответов

Решение

Addslashes обычно недостаточно хорош для работы с многобайтовыми кодированными строками.

Это добавляет косые черты к:

\x00, \n, \r, \, ', " and \x1a. characters.

Где addlashes только добавляет косые черты к

' \ and NUL

Статья Илиаса также довольно подробно о его функциональности

Резко опровергнутый ответ GS на самом деле довольно прав.

Стандартный SQL использует удвоение, чтобы избежать буквального апострофа. Нестандартное использование обратного слеша в MySQL для экранирования является настройкой по умолчанию, но его можно отключить, и часто это происходит, в частности, в sql_mode ANSI.

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

Проблема многобайтовой кодировки также важна, если вы по-прежнему используете те противные восточноазиатские кодировки, которые повторно используют младшие 128 символов, но тогда вы действительно хотите использовать вместо этого UTF-8. С другой стороны, \ n-экранирование не имеет значения, поскольку MySQL вполне может успешно справиться с необработанным переводом строки в выражении.

mysql_real_escape_string делает намного больше, чем addslashes делает.

Аддлэш работает на чистом ascii, ничего не зная о базе данных. Это ускользает от:

  • '\'
  • "\"
  • \\\
  • ASCII 0\0,

Цель mysql_real_escape_string- "создать допустимую строку SQL, которую можно использовать в операторе SQL". mysql_real_escape_string учитывает текущий набор символов соединения (именно поэтому вы всегда должны передавать действительный объект $mysql).

Это делает следующее (взято из документации MySQL C API):

  • Зашифровывает: \, ', ", ASCII 0, \n, \r, а также Control+Z таким образом, что не вызовет проблем
  • обеспечивает 0 байт завершает строку (в C api)
  • может выполнять многобайтовое преобразование (ascii) в широкие символы, если в базе данных, связанной с $mysql, используется широкий набор символов.

Я действительно не знаю, как PHP хранит строки внутри, но суть в том, что все это доступно PHP, когда вы используете mysql_real_escape_string, Я думаю, главное отличие mysql_real_escape_string учитывает набор символов соединения, где addslashes не может (он даже не знает, к какой БД вы подключены).

somedb_real_escape_string() является конкретной базой данных, addslashes() не является.

В случае MySQL это означает:

mysql_real_escape_string () вызывает библиотечную функцию MySQL mysql_real_escape_string, которая добавляет обратную косую черту к следующим символам: \x00, \n, \r, \, ', "и \ x1a.

(Из руководства.)

Зачем нам нужны специфичные для БД функции, такие как mysql_real_escape_string()?

На самом деле, большую часть времени мы не делаем.
Эта функция требуется для нескольких крайне редких кодировок, а также для небольшого обновления журналов и дампов mysql.

такое веб-приложение, которое использует addlashes(), все еще уязвимо для SQL-инъекций?

Пока он использует какой-либо однобайтовый набор символов или utf8 - он абсолютно безопасен с addlashes().

Что он может сделать, чего не делает addlashes()?

Он может защитить строковый литерал SQL в случае некоторых редких кодировок.

Тем не менее, он не может сделать это сам по себе. Правильное кодирование должно быть установлено с помощью mysql_set_charset() функция первая Если эта функция не была использована, mysql_real_escape_string() будет вести себя точно так же, как addslashes() с точки зрения обработки charset - не было бы никакой разницы вообще.

Функция PHP mysql_real_escape_string, более или менее, спросит mysql, какие символы должны быть экранированы, где функция addlashses просто добавит обратную косую черту перед любой одиночной кавычкой ('), двойной кавычкой ("), backslash () или символ NUL (байт NULL).

Два практических эффекта заключаются в том, что addlashes имеет тенденцию плохо работать с многобайтовыми символами, и, что более важно, спрашивая mysql, какие символы необходимо экранировать, вы избегаете возможной будущей совместимости. Использование асслашей похоже на жесткое кодирование пары конкретных символов в escape-последовательности.

Согласно руководству по PHP:

mysql_real_escape_string () вызывает библиотечную функцию MySQL mysql_real_escape_string, которая добавляет обратную косую черту к следующим символам: \x00, \n, \r, \, ', "и \x1a.

Единственное реальное различие, о котором я знаю, состоит в том, что mysql_real_escape_string() будет учитывать набор символов базы данных при экранировании входной строки. Ни одна из функций не будет экранировать символы подстановки% и _, что все еще оставляет сценарий открытым для некоторого внедрения SQL.

Он должен экранировать строки для MySQL так, как этого не делают другие средства цитирования.

Однако гораздо предпочтительнее использовать интерфейс mysqli и использовать параметризованные подготовленные запросы вместо того, чтобы убедиться, что все ваши строки правильно экранированы. Использование параметризованных запросов устраняет необходимость в такой грязной работе со строками и значительно снижает риск внедрения SQL-кода.

Изменить: Я немного поясню, почему я считаю цитирование плохой идеей: легко забыть, когда и где вам нужно цитировать - должна ли ваша переменная быть строкой или числом, была ли она уже в кавычках и т. Д. A Параметризованный запрос не имеет ни одной из этих проблем, и необходимость цитирования полностью устранена.

В соответствии с моим пониманием mysql_real_escape_string() выполняет работу более точно, поскольку она взаимодействует с базой данных, чтобы сначала проверить, что нужно кодировать, а затем кодировать соответственно, не так ли? Так что там для этого работать более эффективно

почему вы хотите сначала выполнить добавление косых черт, а затем удалить эти косые черты, прежде чем показывать, что данные и все еще добавления косых черт не так эффективны, как mysql_real_escape_string, используйте mysql_real_escape_string, если вы используете mysql_query, например, функции db, для запросов, или я думаю, что PDO с prepare лучше, поскольку mysql_real_escape_string специфична для БД

При использовании PHP PDO используйте $conn->quote($string). См.: https://www.php.net/manual/en/pdo.quote.php

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