Введите текст и специальные символы и MySQL - PullRequest
2 голосов
/ 01 февраля 2010

У меня есть простое текстовое поле в форме, и я хочу безопасно хранить специальные символы в базе данных после POST или GET, и я использую код ниже. $ текст = mysql_real_escape_string (htmlspecialchars_decode (stripslashes (обрезки ($ _ GET [ "текст"])), ENT_QUOTES));

Когда я читаю текст из базы данных и помещаю его в текстовое значение, я использую приведенный выше код.

$text=htmlspecialchars($text_from_DB,ENT_QUOTES,'UTF-8',false);
<input type="text" value="<?=$text?>" />

Я пытаюсь сохранить в базе данных без специальных символов (что означает, что я не хочу писать в поле базы данных "или ')

На самом деле при записи в базу данных выполните htmlspecialchars_decode текст.

При записи в текстовое поле формы выполните htmlspecialchars текст.

Является ли это наилучшим подходом для безопасной записи специальных символов в базу данных?

Ответы [ 4 ]

3 голосов
/ 01 февраля 2010

У вас есть правильная идея сохранить текст в базе данных как сырой. Не уверен, для чего нужны все сущности HTML-сущности; вам не нужно делать это для вставки базы данных.

[Единственная причина, по которой я могу подумать, почему вы можете попытаться декодировать входящий ввод для базы данных, заключается в том, что вы обнаруживаете, что получаете входные символы, такие как &#352;, при вводе формы. Если это происходит, то это потому, что пользователь вводит символы, которых нет в кодировке, используемой страницей с формой. Эта форма кодирования является полностью поддельной, потому что тогда вы не сможете различить пользователя, набравшего Š и буквально набрав &#352;! Вам следует избегать этого, используя кодировку UTF-8 для всех ваших страниц и содержимого, поскольку все возможные символы вписываются в эту кодировку.]

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

$category= trim($_POST['category']);
mysql_query("SELECT * FROM things WHERE category='".mysql_real_escape_string($category)."'");

(или использовать параметризованные запросы, чтобы избежать необходимости вручную экранировать его.) При помещении содержимого в HTML:

<input type="text" name="category" value="<?php echo htmlspecialchars($category); ?>" />

(вы можете определить вспомогательную функцию с более коротким именем, например function h($s) { echo htmlspecialchars($s, ENT_QUOTES); }, если вы хотите сократить количество набираемых текстов в шаблонах.)

И ... вот и все. Вам не нужно обрабатывать строки, которые выходят из базы данных, поскольку они уже являются необработанными строками. Вам не нужно обрабатывать входные строки (*), кроме какой-либо валидации поля приложения, которую вы хотите выполнить.

*: хорошо, за исключением случаев, когда magic_quotes_gpc включен, и в этом случае вам нужно либо stripslashes() все, что приходит от get / post / cookie, либо, мой любимый вариант, просто сразу же завершиться неудачей:

if (get_magic_quotes_gpc())
    die(
        'Magic quotes are turned on. They are utterly bogus and no-one should use them. '.
        'Turn them off, you idiot, or I refuse to run. So there!'
    );
1 голос
/ 01 февраля 2010

Я бы хотел отметить пару вещей:

  1. нет ничего плохого в сохранении таких символов, как ' и " в базе данных, SQL-инъекции - это просто вопрос манипуляции со строками, на самом деле они не имеют ничего общего с SQL или базами данных - проблема только зависит от того, как строится строка запроса. Если вы хотите написать свои собственные запросы (не рекомендуется), вам не нужно кодировать каждый апостроф или двойную кавычку: просто экранируйте их один раз, чтобы построить безопасную строку, и сохраните их в базе данных. Лучшим подходом является использование PDO, как уже упоминалось, или использование mysqli extension, которое разрешает запросы с подготовленными утверждениями

  2. htmlentities() и аналогичные функции следует использовать при отправке данных в качестве вывода в браузер, а не для кодирования данных, которые должны храниться в базе данных, по крайней мере по двум причинам: во-первых, это бесполезно, БД не ' не заботится о HTML-сущностях, он просто содержит данные; во-вторых, вы должны всегда рассматривать данные, поступающие из базы данных, как потенциально небезопасные, поэтому вы должны сохранить их в «сыром» формате и закодировать их при использовании .

1 голос
/ 01 февраля 2010

Когда вы пишете в дб, используйте htmlentities , но когда вы читаете обратно, используйте html_entity_decode function.

В качестве идентификатора, если вам нужна безопасность, для строк используйте mysql_real_escape_string , а для чисел используйте intval .

0 голосов
/ 01 февраля 2010

Лучший подход для безопасной записи в БД - использовать уровень абстракции PDO и использовать подготовленные операторы.

http://www.php.net/manual/en/intro.pdo.php

Хороший учебник (я узнал из этого) -

http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html

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

...