Зачем нужны функции, специфичные для БД, такие как mysql_real_escape_string ()? Что это может сделать, что addlashes () не делает?
Игнорируя на данный момент превосходную альтернативу параметризованных запросов, является webapp, который использует addlashes (), исключительно все еще уязвимый для SQL-инъекции, и если да, то как?
Обычно при использовании многобайтовых закодированных строк добавление обычно недостаточно.
Он добавляет косые черты:
\x00, \n, \r, \, ', " and \x1a. characters.
Где addlashes добавляет только косые черты
' \ and NUL
В статье Ilias также подробно описывается ее функциональность
gs's резко сокращенный ответ на самом деле выглядит правильно.
Стандартный SQL использует удвоение, чтобы избежать буквального апострофа. Нестандартное использование MySQL обратных косых черт для экранирования является настройкой по умолчанию, но его можно отключить и часто, в частности, в sql_mode ANSI.
В этом случае будет работать только удвоенный синтаксис, и любое приложение, которое вы используете addlashes (или другой метод ad-hoc escaping), сломается. mysql_real_escape_string будет использовать тот способ, который лучше всего подходит для sql_mode соединения.
Проблема многобайтового кодирования также важна, если вы все еще используете эти неприятные восточно-азиатские кодировки, которые используют более 128 символов, но тогда вы действительно хотите использовать UTF-8. \ n-escaping, с другой стороны, не вызывает беспокойства, так как MySQL вполне может справиться с необработанной новой строкой в заявлении.
mysql_real_escape_string делает намного больше, чем делает addlashes .
addslashes работает на чистом ascii, ничего не зная о базе данных. Это ускользает:
'
→ \'
"
→ \"
\
→ \\
0
→ \0
. Цель mysql_real_escape_string состоит в том, чтобы «создать юридическую строку SQL, которую вы можете использовать в SQL-заявлении». mysql_real_escape_string учитывает текущий набор символов соединения (поэтому вы всегда должны передавать действительный объект $ mysql).
Он выполняет следующие действия (взятые из документации API MySQL C):
\
, '
, "
, ASCII 0
, \n
, \r
и Control+Z
таким образом, чтобы это не вызывало проблем 0
байт завершает строку (в C api) Я не знаю, как 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.
является webapp, который использует addslashes (), исключительно все еще уязвимый для SQL-инъекции?
Пока он использует какую-либо однобайтовую кодировку или utf8 – это абсолютно безопасно с addslashes ().
Что это может сделать, что addlashes () не делает?
Он может защитить строковый литерал SQL в случае некоторых редких кодировок.
Однако он не может сделать это сам по себе. Правильная кодировка должна быть установлена с использованием функции mysql_set_charset()
. Если эта функция не была использована, mysql_real_escape_string()
будет вести себя точно так же, как addslashes()
с точки зрения обработки кодировки – не было бы никакой разницы .
Единственное реальное отличие, о котором я знаю, это то, что mysql_real_escape_string () примет во внимание набор символов базы данных при выходе из входной строки. Ни одна из функций не будет выдавать символы wild card% и _, которые все еще оставляют скрипт открытым для некоторой инъекции SQL.
Согласно руководству PHP :
mysql_real_escape_string () вызывает библиотечную функцию MySQL mysql_real_escape_string, которая добавляет обратную косую черту к следующим символам: \ x00, \ n, \ r, \, ', "и \ x1a.
Функция mysql_real_escape_string PHP будет, более или менее, запросить mysql, какой символ (ы) должен быть экранирован , где функция addlashses просто добавит обратную косую черту перед и любую одинарную цитату ('), двойную кавычку («), обратную косую черту () или NUL (NULL байт).
Два практических эффекта: addlashes имеет тенденцию не работать хорошо с многобайтными символами, и, что более важно, задавая mysql, какие символы нужно избегать, вы избегаете возможной будущей совместимости. Использование assslashes вроде как hardcoding несколько специфических символов в escape-последовательность.
Он должен избегать строк для MySQL таким образом, что другие объекты цитирования не работают.
Однако гораздо предпочтительнее использовать интерфейс mysqli и использовать параметризованные подготовленные запросы, а не пытаться убедиться, что все ваши строки правильно экранированы. Использование параметризованных запросов устраняет необходимость в такой беспорядочной работе строки и сильно смягчает риск внедрения SQL.
Редактирование: я немного разъясню, почему я считаю цитату плохой идеей: легко забыть, когда и где вам нужно указывать – должна ли ваша переменная быть строкой или номером, независимо от того, была ли она уже указана и т. Д. A параметризованный запрос не имеет ни одной из этих проблем , и необходимость в цитировании полностью устранена.
Согласно моему пониманию mysql_real_escape_string () делает работу более точно, поскольку она обменивается данными с db, чтобы сначала проверить, что нужно кодировать и затем кодировать соответственно, не так ли? Так что там для него работают более эффективно
почему вы хотите сначала сделать addlashes, а затем вы удалите эти косые черты, прежде чем показывать, что данные и все еще addlashes не так эффективны, как mysql_real_escape_string, используйте mysql_real_escape_string, если вы используете mysql_query, например, функции db для запроса, или я думаю, что PDO с подготовкой лучше , поскольку mysql_real_escape_string имеет значение db