PHP & mySQL: когда именно использовать htmlentities?

ПЛАТФОРМА: PHP & mySQL

В моих экспериментальных целях я пробовал несколько инъекций XSS самостоятельно на своем собственном веб-сайте. Подумайте об этой ситуации, когда у меня есть вход в форму textarea. Поскольку это текстовое поле, я могу вводить текст и всевозможные (английские) символы. Вот мои наблюдения:

А). Если я применяю только strip_tags и mysql_real_escape_string и не использую htmlentities на моем вводе непосредственно перед вставкой данных в базу данных, запрос ломается, и я попадаю с ошибкой, которая показывает мою структуру таблицы из-за ненормального завершения.

Б). Если я применяю strip_tags, mysql_real_escape_string и htmlentities на моем входе непосредственно перед вставкой данных в базу данных, запрос НЕ разбивается, и я могу успешно вставлять данные из текстового поля в мою базу данных.

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

  1. Когда нужно использовать только htmlentities? Должен ли он использоваться непосредственно перед вставкой данных в БД или каким-то образом получить данные в БД, а затем применить htmlentities, когда я пытаюсь показать данные из БД?

  2. Если я следую методу, описанному в пункте B) выше (который, я считаю, является наиболее очевидным и эффективным решением в моем случае), мне все еще нужно применять htmlentities, когда я пытаюсь показать данные из БД? Если да, то почему? Если нет, почему бы и нет? Я спрашиваю об этом, потому что это действительно сбивает меня с толку после того, как я прошел этот пост по адресу: http://shiflett.org/blog/2005/dec/google-xss-example

  3. Тогда есть еще одна функция PHP: html_entity_decode . Могу ли я использовать это для отображения моих данных из БД (после выполнения моей процедуры, как указано в пункте B), поскольку htmlentities применялись на моем входе? Какой из них я должен предпочесть: html_entity_decode и htmlentities и когда?

ПРЕДВАРИТЕЛЬНАЯ СТРАНИЦА:

Я подумал, что это может помочь добавить некоторые более конкретные детали конкретной ситуации здесь. Учтите, что есть страница «Предварительный просмотр». Теперь, когда я отправляю входные данные из текстового поля, страница предварительного просмотра получает вход и показывает его html, и в то же время скрытый ввод собирает этот вход. Когда нажата кнопка отправки на кнопке предварительного просмотра, данные со скрытого ввода отправляются на новую страницу и эта страница вставляет данные, содержащиеся в скрытом вводе, в БД. Если я не применяю htmlentities, когда форма изначально отправлена ​​(но применяются только strip_tags и mysql_real_escape_string), и в текстовом поле есть вредоносный ввод, скрытый ввод прерывается, а последние несколько символов скрытого ввода видимо воспринимаются как " /> on поэтому это нежелательно. Поэтому, помня об этом, мне нужно что-то сделать, чтобы сохранить целостность скрытого ввода на странице предварительного просмотра и все же собрать данные на скрытом входе, чтобы он не нарушил его. Я об этом говорю? Извините за задержку в публикации этой информации.

Заранее спасибо.

Вот общее правило.

Перемещайте переменные в последний момент .

Вы хотите, чтобы ваши переменные были чистыми представлениями данных. То есть, если вы пытаетесь сохранить фамилию кого-то по имени «O'Brien», то вы определенно не хотите этого:

 O'Brien O\'Brien 

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

 $name = "O'Brien"; $sql = "SELECT * FROM people " . "WHERE lastname = '" . mysql_real_escape_string($name) . "'"; $html = "<div>Last Name: " . htmlentities($name, ENT_QUOTES) . "</div>"; 

Вы никогда не хотите, чтобы htmlentities -encoded strings хранились в вашей базе данных. Что происходит, когда вы хотите создать CSV или PDF или что-либо, что не является HTML?

Храните данные в чистоте и выходите только в конкретном контексте.

  1. Только до того, как вы напечатаете значение (независимо от БД или из $ _GET / $ _ POST) в HTML. htmlentities не имеют ничего общего с базой данных.
  2. B – избыток. Перед вставкой в ​​базу данных необходимо указать mysql_real_escape_string и htmlentities перед печатью в HTML. Вам не нужно снимать теги, после того, как теги htmlentities будут отображаться на экране как <br /> и т. Д.

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

 3. See above 

По сути, вы должны использовать mysql_real_escape_string перед mysql_real_escape_string базы данных (чтобы предотвратить SQL-инъекцию), а затем htmlentities и т. Д. В точке вывода.

Вы также захотите применить проверку работоспособности ко всем пользовательским вводам , чтобы гарантировать (например), что числовые значения действительно являются числовыми и т. Д. В этот момент полезны такие функции, как is_int , is_float и т. Д. (Дополнительную информацию об этих функциях и других подобных возможностях см. В разделе функций обработки переменных руководства PHP).

Я прошел через это раньше и узнал две важные вещи:

Если вы получаете значения из $ _POST / $ _ GET / $ _ REQUEST и планируете добавить в БД, используйте функцию mysql_real_escape_string для дезинфекции значений. Не кодируйте их с помощью htmlentities.

Почему бы просто не закодировать их с помощью htmlentities и не поместить их в базу данных? Ну, вот что – цель состоит в том, чтобы сделать данные максимально содержательными и чистыми, и когда вы кодируете данные с помощью htmlentities, таких как Jeff's Dog, становится собакой Джеффа …, которая заставит контекст данных потерять смысл. И если вы решите внедрить сервисы REST и вы получите эту строку из БД и поместите ее в JSON – это будет похоже на собаку Джеффа, которая не очень хороша. Вам придется добавить еще одну функцию для декодирования.

Предположим, что вы хотите найти «Jeff's Dog», используя SQL «select * from table where field = 'Jeff's Dog», вы не найдете его, поскольку «Jeff's Dog» не соответствует «Jeff & s Dog». Плохо, а?

Чтобы выводить буквенно-цифровые строки (из типа CHAR) на веб-страницу, используйте htmlentities – ВСЕГДА!