2009-02-10 4 views
20

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

Игнорируя на данный момент превосходную альтернативу параметризованных запросов, является webapp, который использует addslashes(), исключительно все еще уязвимый для SQL-инъекции, и если да, то как?

ответ

19

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

+5

Любая кодировка с допустимым многобайтовым символом, заканчивающимся на 0x5c, может прокрасть кавычки мимо 'addslashes()'. Крис Шифлетт имеет отличный пример в своем блоге с использованием GBK. http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string – Matthew

+1

Вы _right_, но вы не сказали _how_. – bobobobo

+1

Совсем наоборот - в целом добавляет, все в порядке, но в некоторых крайне редких случаях нам действительно нужны mres. –

0

Предполагается избежать строк для MySQL таким образом, что другие объекты цитирования не используют.

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

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

+0

Думаю, я должен уточнить, что я прекрасно понимаю превосходство параметризованных запросов :) –

3

somedb_real_escape_string() специфична для конкретной страны, addslashes() нет.

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

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

(Из инструкции.)

1

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

+0

% и _ не имеют ничего общего с SQL-инъекцией. –

+0

В MySQL% может использоваться как дикая карта в операциях GRANT. Кроме того, MySQL рассматривает _ как односимвольные символы в заявлениях. – nabrond

+0

% и _ не имеют никакого отношения к SQL-инъекции. –

19

Он добавляет косую черту на:

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

Где addslashes только добавляет косую черту в

' \ and NUL 

Ilias article также довольно подробная по своей функциональности

1

Согласно PHP manual:

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

5

Жестко отрицательный ответ gs на самом деле является правдоподобным.

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

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

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

1

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

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

0

Согласно моему пониманию mysql_real_escape_string() выполняет работу более точно, поскольку она обменивается данными с db, чтобы сначала проверить, что нужно кодировать, а затем кодировать соответственно, не так ли? Так что для его работы более effeciently

, почему вы хотите, чтобы сначала сделать addslashes, а затем вы будете удалить, что слэши перед показом, что данные и по-прежнему addslashes не так эффективно, как mysql_real_escape_string, используйте mysql_real_escape_string если вы используете mysql_query как БД функций для quering, или я думаю, что ПДО с подготовкой является лучшим способом, так как mysql_real_escape_string является дб конкретным

4

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

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

  • '\'
  • "\"
  • \\\
  • 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)
  • может выполнять многобайтного (ASCII) для широкого преобразования символов, если БД связан в $ MySQL использует AW идеал набор символов.

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

+0

Большинство пунктов не имеет смысла. addslashes создает не менее легальную строку SQL, что бы это ни значило. mres вообще не преобразует символов. и нет смысла прерывать строки с помощью NUL. Откуда у тебя все это? –

+0

Прямо из документации. Мультибайт может быть преобразован в широкий. ["Строка, на которую указана длина, должна быть длиной в байтах длиной. Вы должны выделить для буфера как минимум длину * 2 + 1 байт (в худшем случае каждый символ может быть закодирован как два байта, и вам нужно место для завершения нулевого байта.) "] (http://dev.mysql.com/doc/refman/5.7/en/mysql-real-escape-string.html). Я предполагаю, что библиотека PHP вызывает функцию API-интерфейса 'mysql_real_escape_string' под капотом. – bobobobo

2

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

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

- это webapp, который использует addlashes(), исключительно уязвимый для SQL-инъекции?

До тех пор, как он использует любой однобайтные кодовую или utf8 - это совершенно безопасно с addslashes().

Что это может сделать, что добавляетс() нет?

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

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

+0

__Когда он использует любую однобайтную кодировку или utf8__ - она ​​абсолютно безопасна с помощью добавок(). Зачем вам использовать 'addlashes' как практику, где вам внезапно приходится менять свою практику, как только вы работаете с Unicode? – bobobobo

+0

Очень жаль, что с PHP вы должны [установить набор символов на уровне сервера или использовать 'mysqli_set_charset'] (http://www.php.net/manual/en/mysqli.real-escape-string.php). Это не относится к C. – bobobobo

+1

@bobobobo "[addslashes совершенно безопасно с] utf8 ... Почему вы используете addlashes [если] вам вдруг придется изменить свою практику, как только вы работаете с Unicode?" Ты не понимаешь; UTF-8 * - * Юникод. Единственными уязвимыми случаями являются ** набор символов без Unicode **, такой как GBK. То есть, addlashes() совершенно безопасен для любого, кто использует Unicode, и является только небезопасным для людей, которые предпочитают использовать странные национальные наборы символов ** вместо ** Unicode. – Quuxplusone

Смежные вопросы