Расшифровка mysql_real_escape_string () для вывода HTML - PullRequest
11 голосов
/ 04 апреля 2010

Я пытаюсь защитить себя от SQL инъекций и использую:

mysql_real_escape_string($string);

При публикации HTML это выглядит примерно так:

<span class="\&quot;className\&quot;">
<p class="\&quot;pClass\&quot;" id="\&quot;pId\&quot;"></p>
</span>

Я не уверен, сколько других вариаций добавляет real_escape_string, поэтому я не хочу просто заменять несколько и пропускать другие ... Как я могу "декодировать" это обратно в правильно отформатированный HTML, например:

html_entity_decode(stripslashes($string));

Ответы [ 9 ]

13 голосов
/ 04 апреля 2010

Страница справочника mysql_real_escape_string () сообщает, какие символы экранированы:

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

Вы можете успешно отменить экранирование, заменив этих экранированных персонажей их неэкранированными формами.

mysql_real_escape_string() не следует использовать для очистки HTML, хотя ... нет причин использовать его перед выводом данных веб-страницы. Он должен использоваться только для данных, которые вы собираетесь поместить в базу данных. Ваш процесс очистки должен выглядеть примерно так:

Input

  1. Принимать пользовательский ввод из формы или HTTP-запроса
  2. Создать запрос к базе данных, используя mysql_real_escape_string()

выход

  1. Извлечение данных из базы данных
  2. Выполните любые пользовательские данные через htmlspecialchars() перед печатью

Использование другого драйвера базы данных, такого как MySQLi или PDO , позволит вам использовать подготовленные операторы, которые позаботятся о том, чтобы избежать большинства входных данных для вас. Однако, если вы не можете переключиться или воспользоваться ими, обязательно используйте mysql_real_escape_string() ... просто используйте его только перед вставкой данных.

9 голосов
/ 04 апреля 2010

Вы все испортили.

mysql_real_escape_string не требует декодирования.

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

Не говоря уже о том, что любое побег является устаревшим, и вы должны

использовать подготовленные заявления

вместо любой escape-строки.

Итак, никогда не убегай, никогда не декодируй.
Проблема решена.

8 голосов
/ 04 апреля 2010

mysql_real_escape_string используется для предотвращения внедрения SQL при хранении пользовательских данных в базе данных, но лучшим способом будет использование привязки данных с использованием PDO (например). Я всегда рекомендую использовать это вместо того, чтобы возиться с побегом.

Это, как говорится, в отношении вашего вопроса о том, как отображать его впоследствии - после того, как данные сохранены, когда вы извлекаете их, данные полны и действительны без необходимости их «удаления». Если вы не добавили свои собственные экранирующие последовательности, пожалуйста, не делайте этого.

0 голосов
/ 08 ноября 2017

используйте следующую функцию для удаления косой черты при отображении на странице HTML:

stripslashes ();

например. $ HTML = stripslashes ($ HTML); ИЛИ ЖЕ $ HTML = stripslashes ($ строка [ "имя_поля"]);

0 голосов
/ 30 января 2017

Даже если это старый вопрос ... У меня была та же проблема, что и у Питера Крейга. На самом деле я имею дело со старой CMS. Чтобы предотвратить SQL-инъекцию, все значения $ _POST и $ _GET являются «sql-escape-экранированными». К сожалению, это сделано в центральной точке, поэтому все ваши модули получают все данные sql-escape-escape! В некоторых случаях вы хотите напрямую отобразить эти данные, чтобы вы столкнулись с проблемой: как отобразить строку с экранированием sql, не получая ее из БД? Ответ: использовать полоски (НЕ полосы!)

http://php.net/manual/en/function.stripcslashes.php

0 голосов
/ 04 августа 2016

Ну, я попробовал это по старинке и пока не вижу ничего плохого в своем подходе. Очевидно, это немного грубо, но это делает работу:

function mysql_unreal_escape_string($string) {
    $characters = array('x00', 'n', 'r', '\\', '\'', '"','x1a');
    $o_chars = array("\x00", "\n", "\r", "\\", "'", "\"", "\x1a");
    for ($i = 0; $i < strlen($string); $i++) {
        if (substr($string, $i, 1) == '\\') {
            foreach ($characters as $index => $char) {
                if ($i <= strlen($string) - strlen($char) && substr($string, $i + 1, strlen($char)) == $char) {
                    $string = substr_replace($string, $o_chars[$index], $i, strlen($char) + 1);
                    break;
                }
            }
        }
    }
    return $string;
}

Это должно охватывать большинство случаев.

0 голосов
/ 22 сентября 2013

Мне было интересно, почему эта процедура не имеет сопутствующей процедуры декодера. Он, вероятно, интерпретируется MySQL точно так же, как если бы он не был экранирован. Вы получаете неперекрытые результаты, когда вы делаете $row=mysql_fetch_array($res, MYSQL_ASSOC)';

0 голосов
/ 04 апреля 2010

Не уверен, что происходит с форматированием, как я вижу, но ваша HTML-форма

<span class="\&quot;className\&quot;">
<p class="\&quot;pClass\&quot;" id="\&quot;pId\&quot;"></p>
</span>

должно быть просто;

<span class="className">
<p class="pClass" id="pId"></p>
</span>

Когда вы получаете его обратно, перед тем, как поместить его в базу данных, вы избегаете его, используя mysql_real_escape_string (), чтобы убедиться, что вы не подвергнетесь атаке SQL-инъекций.

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

Когда вы выводите его из базы данных (или выводите ЛЮБОЕ из него пользователям в виде html), вы снова экранируете его, готовый к тому месту, куда он пойдет следующим (html), с помощью htmlentities () и т. Д. Для защиты ваших пользователей от XSS атаки.

Это формирует часть EO мантры FIEO, Filter Input, Escape Output, которую вы должны татуировать на внутренней стороне своих век.

0 голосов
/ 04 апреля 2010

Я думаю, что ряд других ответов пропустили очевидную проблему ...

Вы используете mysql_real_escape_string для введенного содержимого (как следует, если не используете подготовленные операторы).

Ваша проблема с выводом.

В настоящее время проблема заключается в том, что вы вызываете html_entity_decode. Просто полоски - это все, что вам нужно для восстановления исходного текста. html_entity_decode - это то, что портит ваши цитаты и т. д., так как они меняют их. Вы действительно хотите выводить html, а не просто текст (когда вы используете html_entities и т. Д.). Вы декодируете то, что хотите закодировать.

Если вы хотите, чтобы отображалась только текстовая версия, вы можете использовать объекты. Если вас беспокоят плохие теги, используйте стрип-теги и разрешите использовать только те теги, которые вам нужны (например, b, i и т. Д.).

Наконец, не забудьте кодировать и декодировать в правильном порядке. если вы запустили mysql_real_escape_String (htmlentities ($ str)), то вам нужно запустить html_entity_decode (stripslashes ($ str)). Порядок операций имеет значение.

ОБНОВЛЕНИЕ: я не осознавал, что html_entity_decode также удаляет косые черты. Это не было четко задокументировано на этой странице, и я просто никогда этого не замечал. Я все равно буду автоматически запускать его, так как большинство HTML, которые я представляю, я хочу оставить как сущности, и даже когда я этого не сделаю, я предпочитаю принимать это решение за пределами моего класса DB, в каждом конкретном случае. Таким образом, я знаю, что косые черты исчезли.

Похоже, что оригинальный постер работает с htmlentities (или его программа ввода, как это делает tinymce для него), и он хочет вернуть его обратно к содержанию. Таким образом, html_entity_decode ($ Str) должен быть всем, что требуется.

...