PHP и MySQL: когда именно использовать htmlentities? - PullRequest
21 голосов
/ 16 января 2010

ПЛАТФОРМА: PHP и MySQL

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

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

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

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

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

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

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

Страница предварительного просмотра:

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

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

Ответы [ 4 ]

51 голосов
/ 16 января 2010

Вот общее эмпирическое правило.

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

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

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, в вашей базе данных. Что происходит, когда вы хотите сгенерировать CSV, PDF или что-то, что не HTML?

Содержите данные в чистоте и избегайте только для конкретного контекста момента.

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

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

3. See above
5 голосов
/ 16 января 2010

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

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

0 голосов
/ 23 августа 2012

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

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

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

Предположим, что вы хотите найти "Собаку Джеффа", используя SQL "select * из таблицы, где field = 'Jeff \' s Dog '", вы не найдете его, поскольку "Собака Джеффа" не соответствует "Jeff & s" Собака." Плохо, а?

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

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