Когда лучше всего санировать пользовательский ввод?

пользователь равен ненадежным. Никогда не доверяйте вводу ненадежного пользователя. Я понимаю. Тем не менее, мне интересно, когда лучшее время для дезинфекции ввода. Например, вы слепо храните пользовательский ввод, а затем дезинфицируете его всякий раз, когда он доступен/используется, или вы немедленно дезинфицируете вход, а затем сохраняете эту "очищенную" версию? Возможно, есть и некоторые другие подходы, о которых я не думал в дополнение к этим. Я склоняюсь больше к первому методу, потому что любые данные, которые пришли от пользователя к вводу по-прежнему следует подходить осторожно, когда "очищенные" данные все еще могут быть неосознанно или случайно опасны. В любом случае, какой метод люди считают лучшим и по каким причинам?

14 ответов


Мне нравится дезинфицировать его как можно раньше, что означает, что дезинфекция происходит, когда пользователь пытается ввести недопустимые данные. Если есть текстовое поле для их возраста, и они вводят что-то другое, что число, я не позволяю нажатию клавиши для письма пройти.

затем, независимо от того, что читает данные (часто сервер), я делаю проверку здравомыслия, когда я читаю данные, просто чтобы убедиться, что ничего не проскальзывает из-за более определенного пользователя (например, файлы для редактирования вручную или даже изменение пакетов!)

Edit: в целом, санировать рано и санировать в любое время, когда вы потеряли из виду данные даже на секунду (например, Файл Сохранить -> файл открыть)


Я дезинфицирую свои пользовательские данные так же, как Radu...

  1. первая клиентская сторона, использующая как регулярное выражение, так и контроль над допустимыми символами ввод в заданные поля формы с помощью javascript или jQuery, привязанных к событиям, таким как onChange или OnBlur, который удаляет любой запрещенный ввод, прежде чем он может быть представлен. Поймите, однако, что это действительно имеет только эффект, позволяя тем пользователи знают, что данные также будут проверены на стороне сервера. Это больше предупреждение, чем любая реальная защита.

  2. во-вторых, и я редко вижу, что это делается в эти дни, что первая проверка сделано на стороне сервера, чтобы проверить местоположение, откуда отправляется форма. Разрешая отправку формы только со страницы, указанной в качестве действительной расположение, вы можете убить сценарий, прежде чем вы даже читать в каких-либо данных. Предоставленный, этого само по себе недостаточно, так как хороший хакер со своим собственным сервером может "подделать" оба домен и IP-адрес, чтобы он показался вашему скрипту, что он идет из допустимого расположения формы.

  3. далее, и я даже не должен этого говорить, но всегда, и я имею в виду всегда, run ваши сценарии в режиме taint. Это заставляет вас не лениться, а быть прилежным шаг номер 4.

  4. Санируйте пользовательские данные как можно скорее, используя хорошо сформированные данные, которые ожидаются от любого заданного поле на форме. Не принимайте ярлыки, как печально известный 'Волшебный рог единорога ' чтобы продуть ваши грязные чеки... или вы также можете просто отключить проверку заражения в первую очередь для всего хорошего это поможет вашей безопасности. Это все равно что дать психопату острый нож. твое горло, и ты говоришь: "ты действительно не причинишь мне боль этим".

    и вот где я отличаюсь от большинства других на этом четвертом шаге, так как я только дезинфицирую пользователь данные, которые я собираюсь использовать таким образом, чтобы обеспечить безопасность риск, такой как любые системные вызовы, назначения другим переменным или любая запись в сохранить данные. Если я использую только ввод данных Пользователем для сравнения с данными Я сам хранил в системе (поэтому, зная, что мои собственные данные безопасны), тогда я не утруждаю себя дезинфицировать пользовательские данные, так как я никогда не собираюсь нам это делать это представляет собой проблему безопасности. Например, введите имя пользователя как - образец. Я использую ввод имени пользователя пользователем только для проверки его соответствия в моя база данных, и если true, после этого я использую данные из базы данных для выполнения все остальные функции я мог бы вызвать в сценарии, зная, что это безопасно, и никогда после этого снова используйте данные пользователей.

  5. последнее, это отфильтровать все попытки автоматической отправки роботами в эти дни, с помощью система "человеческой аутентификации", такая как Captcha. В наши дни это достаточно важно. что я потребовалось время, чтобы написать мою собственную схему "человеческой аутентификации", которая использует фотографии и вход для 'человека', чтобы войти в то, что они видят на картинке. Я сделал это, потому что Я обнаружил, что системы типа Captcha действительно раздражают пользователей (вы можете сказать по их прищурив глаза от попыток расшифровать искаженные буквы... обычно над и снова и снова). Это особенно важно для сценариев, использующих SendMail или SMTP для электронной почты, так как это избранное для вашего голодного спам-ботов.

чтобы завершить это в двух словах, я объясню это, как я делаю с моей женой... ваш сервер похож на популярный ночной клуб, и чем больше у вас вышибал, тем меньше у вас проблем в ночном клубе. У меня есть два вышибалы за дверью (проверка на стороне клиента и аутентификация человека), один вышибала прямо внутри двери (проверка допустимого местоположения подачи формы... "Это действительно Вы на этом ID"), и еще несколько вышибал в близость к дверь (запуск режима заражения и использование хороших регулярных выражений для проверки пользовательские данные.)

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

или вкратце, как часто говорила моя мама... "Лучше перестраховаться, чем потом жалеть".


к сожалению, почти никто из участников никогда четко понимать, о чем они говорят. Буквально. Только @Kibbee удалось сделать это прямо.

эта тема все о дезинфекции. Но правда в том, что такая вещь, как широко называемая "дезинфекция общего назначения", о которой все так хотят говорить,-это просто не существует.

здесь миллион различных медиумов, требуется это собственные, отличные данные форматирование. более того - даже один определенный носитель требует другого форматирования для его частей. Скажем, форматирование HTML бесполезно для javascript, встроенного в HTML-страницу. Или, форматирование строк бесполезно для чисел в SQL-запросе.

на самом деле, такая "дезинфекция как можно раньше", как предлагается в большинстве ответов, просто невозможно. Поскольку невозможно сказать, в какой именно среде или части среды будут использоваться данные. Сказать, мы готовимся защищаться от "sql-инъекций", избегая всего, что движется. Но упс! - некоторые обязательные поля не были заполнены, и мы должны заполнить данные в форму вместо базы данных... со всеми добавленными косыми чертами.

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

с третьей стороны - ладно, мы сделали все возможное в дезинфекция ужасного, ненадежного и презренного "пользовательского ввода"... но в каком-то внутреннем процессе мы использовали эти самые данные без форматирования (как мы уже сделали все возможное!) - и упс! получили инъекцию второго порядка во всей красе.

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

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

Это зависит от того, какой вид дезинфекции вы делаете.

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

для защиты от атак XSS, вероятно, было бы проще исправить данные, прежде чем они будут сохранены. Однако, как упоминали другие, иногда приятно иметь нетронутую копию именно того, что ввел пользователь, потому что после ее изменения она теряется навсегда. Это почти слишком плохо, что нет дурацкого способа убедиться, что приложение только выпускает дезинфицированный HTML, как вы можете убедиться, что вы не попадетесь на SQL-инъекции использование подготовленных запросов.


рано-это хорошо, определенно, прежде чем пытаться разобрать его. Все, что вы собираетесь вывести позже, или особенно передать другим компонентам (например, shell, SQL и т. д.), должно быть санировано.

но не переходите за борт-например, пароли хэшируются перед их хранением (правильно?). Хэш-функции могут принимать произвольные двоичные данные. И вы никогда не распечатаете пароль (верно?). Поэтому не анализируйте пароли и не дезинфицируйте их.

кроме того, убедитесь, что вы делаете дезинфекция из доверенного процесса-JavaScript / что-либо на стороне клиента хуже, чем бесполезная безопасность/целостность. (Это может обеспечить лучший пользовательский опыт, чтобы потерпеть неудачу рано , хотя-просто сделайте это в обоих местах.)


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

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

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


Perl имеет опцию taint, которая считает весь пользовательский ввод "испорченным", пока он не будет проверен регулярным выражением. Испорченные данные могут использоваться и передаваться, но они портят любые данные, с которыми они соприкасаются, пока не останутся незапятнанными. Например, если пользовательский ввод добавляется к другой строке, новая строка также испорчена. В принципе, любое выражение, содержащее испорченные значения, выводит испорченный результат.

испорченные данные могут быть брошены по желанию (испорченные данные, как это goes), но как только он используется командой, которая влияет на внешний мир, сценарий perl терпит неудачу. Поэтому, если я использую испорченные данные для создания файла, создания команды оболочки, изменения рабочего каталога и т. д., Perl завершится ошибкой безопасности.

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

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


мое мнение заключается в том, чтобы санировать пользовательский ввод, как только клиентская и серверная стороны, я делаю это так

  1. (сторона клиента), позволяет пользователю введите только определенные ключи в поле.
  2. (сторона клиента), когда пользователь переходит к следующему полю с помощью onblur, проверьте ввод, который он ввел против regexp и обратите внимание на пользователя, если что-то не так.
  3. (сторона сервера), снова проверьте вход, если поле должно быть целочисленным, проверьте это (в PHP вы можете использовать is_numeric() ), если поле имеет хорошо известный формат проверить регулярное выражение, все другие ( например, текстовые комментарии ), просто сбежать от них. Если что-то подозрительно, остановите выполнение скрипта и верните пользователю уведомление о том, что данные, которые он ввел, недействительны.

Если что-то действительно выглядит как возможная атака, скрипт отправляет мне почту и SMS, поэтому я могу проверить и maibe предотвратить это, как только возможно, мне просто нужно проверить журнал, где я регистрирую все пользовательские входы, и шаги сценарий, сделанный перед принятием ввода или отклонением его.


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

Я вроде как следую этим основным правилам.

  1. только изменение действий SQL, таких как вставка, обновление, удаление через POST. никогда не получить.
  2. побег все.
  3. если вы ожидаете, что пользовательский ввод будет чем-то, убедитесь, что вы проверяете что это что-то. Например, вы запрашиваете номер, а затем убедитесь, что это номер. Используйте проверки.
  4. использовать фильтры. Очистка нежелательных персонажей.

пользователи-это зло!

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

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


предположим, что все пользователи являются вредоносными. Очистите все входные данные как можно скорее. Точка.


Я санирую свои данные прямо перед тем, как я сделаю какую-либо обработку на нем. Возможно, мне придется взять поля имени и фамилии и объединить их в третье поле, которое будет вставлено в базу данных. Я собираюсь санировать входные данные, прежде чем я даже сделаю конкатенацию, чтобы я не получил никаких ошибок обработки или вставки. Чем скорее, тем лучше. Даже использование Javascript на переднем конце (в веб-настройке) идеально, потому что это произойдет без каких-либо данных, идущих на сервер, чтобы начать с.

страшная часть заключается в том, что вы, возможно, даже захотите начать дезинфицировать данные, выходящие из вашей базы данных. Недавний всплеск атак SQL-инъекций ASPRox, которые происходят вокруг, вдвойне смертельны, потому что он заразит все таблицы базы данных в данной базе данных. Если ваша база данных размещена где-то, где есть несколько учетных записей, размещенных в одной базе данных, ваши данные будут повреждены из-за ошибки кого-то другого, но теперь вы присоединились к рядам хостинг вредоносных программ для ваших посетителей из-за отсутствия первоначальной вины.

конечно, это делает много работы впереди, но если данные критичны, то это достойная инвестиция.


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


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