В PHP при отправке строк в базу данных я должен заботиться о недопустимых символах с помощью htmlspecialchars () или использовать регулярное выражение? - PullRequest
19 голосов
/ 08 июня 2010

Я работаю над формой, в которой пользователь может использовать недопустимые / специальные символы в строке, которая будет отправлена ​​в базу данных Я хочу экранировать / отрицать эти символы в строке и использовал htmlspecialchars () Однако есть ли лучший / более быстрый метод?

Ответы [ 6 ]

31 голосов
/ 08 июня 2010

В базе данных нет «недопустимых» символов. База данных, которая не может хранить некоторые символы, это чепуха. Есть несколько символов service , таких как кавычки, которые используются для разделения строк. Эти символы должны быть просто экранированы, а не исключены.

Чтобы отправить запрос в базу данных, у вас есть 2 варианта:

  1. Создайте запрос обычным способом, чтобы он выглядел точно так же, как SQL-запрос, который вы можете запустить в консоли sql.
    Чтобы сделать это, нужно понять целый набор правил , а не просто «использовать mysql_real_escape_string».
    Правила, такие как:

    • Строки должны быть заключены в кавычки и экранированы. Это единственное значение побега: это просто пробелы! (и некоторые другие символы - символ завершения строки и сам символ выхода). Без окружающих кавычек mysql_real_escape_string просто бесполезен.
    • Числа должны быть явно приведены к его типу. Хотя числам данных можно угрожать, как и строкам, есть некоторые числа, например параметры предложения LIMIT, которые нельзя экранировать и можно только привести.
  2. Для отправки запроса и данных отдельно .
    Это наиболее предпочтительный способ, поскольку он может быть сокращен до «использования привязки». Все строки, числа и параметры LIMIT могут быть связаны - не беспокойтесь вообще.
    Используя этот метод, ваш запрос с заполнителями отправляется в базу данных как есть, а связанные данные отправляются в отдельных пакетах, поэтому он не может вмешиваться. Это похоже на код и данные разделение. Вы отправляете свою программу (сам запрос) отдельно от данных.

Но!

Все сказанное выше охватывает только часть данных запроса.
Но иногда мы должны сделать наш запрос еще более динамичным, добавив операторы или идентификаторы.
В этом случае каждый динамический параметр должен быть жестко задан в нашем скрипте и выбран из этого набора.
Например, чтобы сделать динамическое упорядочение:

$orders  = array("name","price","qty"); //field names
$key     = array_search($_GET['sort'],$orders)); // see if we have such a name
$orderby = $orders[$key]; //if not, first one will be set automatically. smart enuf :)
$query   = "SELECT * FROM `table` ORDER BY $orderby"; //value is safe

или динамический поиск:

$w     = array();
$where = '';

if (!empty($_GET['rooms']))     $w[]="rooms='".mesc($_GET['rooms'])."'";
if (!empty($_GET['space']))     $w[]="space='".mesc($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mesc($_GET['max_price'])."'";

if (count($w)) $where="WHERE ".implode(' AND ',$w);
$query="select * from table $where";

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

и т. Д.

14 голосов
/ 08 июня 2010

Если вы отправляете эти данные в базу данных, обратите внимание на функции escape для вашей базы данных.

То есть для MySQL есть mysql_real_escape_string .

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

Вы также можете использовать подготовленные заявления для обработки данных:

$dbPreparedStatement = $db->prepare('INSERT INTO table (htmlcontent) VALUES (?)');
$dbPreparedStatement->execute(array($yourHtmlData));

Или немного больше объяснения:

$dbPreparedStatement = $db->prepare('INSERT INTO table (htmlcontent) VALUES (:htmlcontent)');
$dbPreparedStatement->execute(array(':htmlcontent' => $yourHtmlData));

Если вы хотите сохранить разные типы данных, используйте bindParam для определения каждого типа, то есть целое число может быть определено как: $db->bindParam(':userId', $userId, PDO::PARAM_INT);. Пример:

$dbPreparedStatement = $db->prepare('INSERT INTO table (postId, htmlcontent) VALUES (:postid, :htmlcontent)');
$dbPreparedStatement->bindParam(':postid', $userId, PDO::PARAM_INT);
$dbPreparedStatement->bindParam(':htmlcontent', $yourHtmlData, PDO::PARAM_STR);
$dbPreparedStatement->execute();

Где $db - ваш объект данных PHP (PDO). Если вы не используете его, вы можете узнать больше об этом на Объекты данных PHP .

2 голосов
/ 08 июня 2010

Прежде всего, вы должны дезинфицировать вещи при отображении, а не перед вставкой в ​​базу данных. SQL-инъекции - другая история, но, вероятно, не по теме.

Во-вторых, если вам вообще не нужно, чтобы пользователи могли публиковать HTML, htmlspecialchars - это все, что вам нужно. Он заботится обо всех специальных символах в HTML.

1 голос
/ 08 июня 2010

Я работаю над формой с возможность для пользователя использовать запрещенные / специальные символы в строка, которая должна быть представлена базы данных.

Пользователи могут пойти намного дальше, чем на самом деле.

Я хочу сбежать / отрицать эти символы в строке и были используя htmlspecialchars (). Однако я хотел бы знать, если есть лучше / быстрее метод.

Использование Очиститель HTML :

HTML Purifier соответствует стандартам Библиотека HTML-фильтров написана на PHP. HTML Purifier не только удалит все вредоносный код (более известный как XSS) с тщательно проверенным, безопасным еще разрешительный белый список.

и решите сами:)

0 голосов
/ 08 июня 2010

Вы не указали, какими могут быть эти недопустимые символы, но вам определенно следует использовать предоставленный механизм API базы данных для экранирования данных. Например, если вы используете MySQL, используйте параметризованные операторы SQL PDO.

0 голосов
/ 08 июня 2010

Это не проблема, которую вы хотите решить самостоятельно. Для этого есть библиотеки, такие как HTML Purifier .

...