ПЛАТФОРМА: PHP & mySQL
В моих экспериментальных целях я пробовал несколько инъекций XSS самостоятельно на своем собственном веб-сайте. Подумайте об этой ситуации, когда у меня есть вход в форму textarea. Поскольку это текстовое поле, я могу вводить текст и всевозможные (английские) символы. Вот мои наблюдения:
А). Если я применяю только strip_tags и mysql_real_escape_string и не использую htmlentities на моем вводе непосредственно перед вставкой данных в базу данных, запрос ломается, и я попадаю с ошибкой, которая показывает мою структуру таблицы из-за ненормального завершения.
Б). Если я применяю strip_tags, mysql_real_escape_string и htmlentities на моем входе непосредственно перед вставкой данных в базу данных, запрос НЕ разбивается, и я могу успешно вставлять данные из текстового поля в мою базу данных.
Поэтому я понимаю, что htmentities должны использоваться любой ценой, но не уверены, когда именно они должны использоваться. С учетом вышеизложенного я хотел бы знать:
Когда нужно использовать только htmlentities? Должен ли он использоваться непосредственно перед вставкой данных в БД или каким-то образом получить данные в БД, а затем применить htmlentities, когда я пытаюсь показать данные из БД?
Если я следую методу, описанному в пункте B) выше (который, я считаю, является наиболее очевидным и эффективным решением в моем случае), мне все еще нужно применять htmlentities, когда я пытаюсь показать данные из БД? Если да, то почему? Если нет, почему бы и нет? Я спрашиваю об этом, потому что это действительно сбивает меня с толку после того, как я прошел этот пост по адресу: http://shiflett.org/blog/2005/dec/google-xss-example
Тогда есть еще одна функция 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?
Храните данные в чистоте и выходите только в конкретном контексте.
Теоретически вы можете делать 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 – ВСЕГДА!