Какой правильный / самый безопасный способ избежать входа на форуме? - PullRequest
7 голосов
/ 07 августа 2009

Я создаю программное обеспечение для форума, используя php и mysql backend, и хочу знать, какой самый безопасный способ избежать пользовательского ввода для сообщений на форуме.

Я знаю о htmlentities () и strip_tags () и htmlspecialchars () и mysql_real_escape_string () и даже о escape-коде javascript (), но я не знаю, что и где использовать.

Какой самый безопасный способ обработки этих трех различных типов ввода (под процессом я имею в виду получение, сохранение в базе данных и отображение):

  1. Заголовок сообщения (который также будет основой постоянной ссылки URL).
  2. Содержание сообщения на форуме ограничено вводом основного текста.
  3. Содержание сообщения на форуме, которое позволяет HTML.

Буду признателен за ответ, который скажет мне, сколько из этих escape-функций мне нужно использовать в комбинации и почему. Спасибо!

Ответы [ 7 ]

8 голосов
/ 07 августа 2009

При генерации вывода HTLM (как вы делаете, чтобы получить данные в поля формы, когда кто-то пытается редактировать сообщение, или если вам нужно повторно отобразить форму, потому что пользователь забыл одно поле, для экземпляр) , вы, вероятно, будете использовать htmlspecialchars(): он будет экранировать <, >, ", ' и & - в зависимости от параметров Вы даете это.

strip_tags удалит теги, если пользователь ввел некоторые из них - и вы, как правило, не хотите, чтобы что-то набранное пользователем просто исчезало ;-)
По крайней мере, не для поля «содержимое» : -)


После того, как вы получили то, что пользователь ввел в форму (т. Е. Когда форма была отправлена) , вам необходимо экранировать ее перед отправкой в ​​БД.
Вот где такие функции, как mysqli_real_escape_string, становятся полезными: они экранируют данные для SQL

Возможно, вы также захотите взглянуть на подготовленные утверждения, которые могут вам немного помочь ;-)
с mysqli - и с PDO

Вы не должны использовать что-либо подобное addslashes: выход из него не зависит от ядра СУБД; Лучше / безопаснее использовать функцию, которая подходит для движка (MySQL, PostGreSQL, ...) , с которым вы работаете: он будет точно знать, что и как избежать.


Наконец, для отображения данных на странице:

  • для полей, которые не должны содержать HTML, следует использовать htmlspecialchars(): если пользователь вводил теги HTML, они будут отображаться как есть, а не вводиться как HTML.
  • для полей, которые могут содержать HTML ... Это немного сложнее: вы, вероятно, захотите разрешить только несколько тегов, а strip_tags (который может это сделать) на самом деле не до задача (это позволит атрибуты разрешенных тегов)
    • Возможно, вы захотите взглянуть на инструмент под названием HTMLPUrifier : он позволит вам указать, какие теги и атрибуты должны быть разрешены - и он генерирует действительный HTML, что всегда приятно ^^
    • Это может занять некоторое время для вычисления, и вы, вероятно, не захотите заново генерировать этот HTML каждый раз, когда он должен отображаться; так что вы можете подумать о том, чтобы сохранить его в базе данных (либо сохраняя только этот чистый HTML, либо сохраняя его и не чистый, в двух отдельных полях - может быть полезно, чтобы люди могли редактировать свои сообщения?)


Это всего лишь несколько указателей ... надеюсь, они помогут вам : -)
Не стесняйтесь спрашивать, если у вас есть более точные вопросы!

4 голосов
/ 07 августа 2009

mysql_real_escape_string() экранирует все, что вам нужно поместить в базу данных mysql. Но вместо этого вы должны использовать подготовленные операторы (в mysqli), потому что они чище и делают любые экранирования автоматически.

Все остальное можно сделать с помощью htmlspecialchars (), чтобы удалить HTML из входных данных, и urlencode (), чтобы поместить вещи в формат для URL.

3 голосов
/ 07 августа 2009

Существует два совершенно разных типа атаки, от которых вы должны защищаться:

  • SQL-инъекция: ввод, который пытается манипулировать вашей БД. mysql_real_escape_string() и addslashes() предназначены для защиты от этого. Первый лучше, но параметризованные запросы еще лучше
  • Межсайтовый скриптинг (XSS): ввод, который при отображении на вашей странице пытается выполнить JavaScript в браузере посетителя, чтобы делать все что угодно (например, украсть данные учетной записи пользователя). htmlspecialchars() является определенным способом защиты от этого.

Разрешить "немного HTML", избегая XSS-атак, очень и очень сложно. Это потому, что есть бесконечные возможности контрабанды JavaScript в HTML. Если вы решили сделать это, безопасный способ - использовать BBCode или Markdown, то есть ограниченный набор разметки, отличной от HTML, которую вы затем конвертируете в HTML, удаляя весь настоящий HTML с htmlspecialchars(). Даже тогда вы должны быть осторожны, чтобы не допустить javascript: URL в ссылках. На самом деле позволить пользователям вводить HTML - это то, что вы должны делать, только если это абсолютно важно для вашего сайта . И тогда вам нужно потратить много времени, чтобы убедиться, что вы полностью понимаете HTML, JavaScript и CSS.

1 голос
/ 07 августа 2009

Ответ на этот пост хороший ответ

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

0 голосов
/ 11 августа 2009

Я второй Джори, не катай свой, иди сюда, чтобы увидеть некоторые из множества возможных атак XSS

http://ha.ckers.org/xss.html

htmlentities () -> превращает текст в html, преобразовывая символы в сущности. Если используется кодировка UTF-8, тогда используйте htmlspecialchars (), так как другие объекты не нужны. Это лучшая защита от XSS. Я использую его для каждой выводимой переменной независимо от ее типа или происхождения, если только я не собираюсь указывать html. Производительность очень мала, и это проще, чем пытаться понять, что нужно убежать, а что нет.

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

mysql_real_escape_string () - экранирует строку для mysql и является вашей защитой от SQL-инъекций из маленьких таблиц Бобби (лучше использовать mysqli и prepare / bind, так как тогда выполняется экранирование, и вы можете избежать большого количества беспорядочных конкатенаций строк) 1010 *

Дается совет избегать ввода HTML, если он не является обязательным, и выбрать BBCode или аналогичный (создайте свой собственный, если необходимо), очень разумно.

0 голосов
/ 10 августа 2009

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

Если вы вставляете простой текст в базу данных, не пытайтесь очистить его при вставке, а вместо этого очистите его на дисплее. То есть используйте htmlentities , чтобы закодировать его как HTML (и передать правильный аргумент charset). Вы хотите кодировать на дисплее, потому что тогда вы больше не доверяете правильности содержимого базы данных, что не обязательно является данностью.

Если вы имеете дело с форматированным текстом (html), все становится сложнее. Удаление «злых» битов из HTML без разрушения сообщения - сложная проблема. На самом деле вам придется прибегнуть к стандартизированному решению, например HTMLPurifier . Однако это обычно слишком медленно для каждого просмотра страницы, поэтому вы будете вынуждены делать это при записи в базу данных. Вы также должны убедиться, что пользователь может видеть свои «очищенные» html и исправить исправленную версию.

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

0 голосов
/ 07 августа 2009

У меня есть тенденция избегать всех символов, которые могут быть проблематичными при отображении страниц, Javascript и SQL одновременно. Он оставляет его для чтения в Интернете и в электронной почте HTML, и в то же время устраняет любые проблемы с кодом. Строка кода vb.NET будет:

SafeComment = Replace( _
              Replace(Replace(Replace( _
              Replace(Replace(Replace( _
              Replace(Replace(Replace( _
              Replace(Replace(Replace( _
                HttpUtility.HtmlEncode(Trim(strInput)), _
                  ":", ":"), "-", "-"), "|", "|"), _
                  "`", "`"), "(", "("), ")", ")"), _
                  "%", "%"), "^", "^"), """", """), _
                  "/", "/"), "*", "*"), "\", "\"), _
                  "'", "'")

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