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

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


person Aaron    schedule 29.08.2008    source источник


Ответы (14)


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

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

Редактировать: В целом, очищайте рано и очищайте каждый раз, когда вы теряете данные из виду даже на секунду (например, «Сохранить файл» -> «Открыть файл»).

person Daniel Jennings    schedule 29.08.2008
comment
... или даже пользователь с отключенным js :/ - person Fluffy; 19.07.2010
comment
Это плохой совет. Вы должны дезинфицировать свои выходы, а не входы. - person csauve; 30.03.2015
comment
@csauve правильно. Не уверен, почему это принятый ответ, когда совершенно ясно, что правильным решением здесь является очистка выходных данных. Не пытайтесь обнаружить плохие или злонамеренные входные данные. Такой подход к проблеме закончился бы попыткой реализовать почти бесконечное количество эвристических решений. Подробнее см. здесь: owasp.org/index.php/ - person RavenHursT; 14.07.2016
comment
Прочитав вопрос и ответ еще раз, Даниэль может интерпретировать «Санитизировать» как «Проверить». Если вы хотите проверить, что ввод соответствует критериям для поля (т. е. должен быть положительным целым числом), сделайте это при вводе. Если вы хотите дезинфицировать, как для защиты от вредоносных значений, сделайте это на выходе. - person csauve; 14.07.2016

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

Эта тема посвящена санитарной обработке. Но правда в том, что такой вещи, как «санитизация общего назначения», о которой все так хотят говорить, просто не существует.

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

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

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

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

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

  • форматирование, а не какая-то "санитизация"
  • непосредственно перед использованием
  • по определенным правилам среды
  • и даже следуя подправилам, необходимым для разных частей этого носителя.
person Your Common Sense    schedule 02.09.2013
comment
Читая ответы, я почувствовал сильное желание опубликовать что-то подобное. - person cHao; 02.09.2013
comment
Похоже, что вместо универсального дезинфицирующего средства нам действительно нужна хорошо спроектированная и гибкая структура для решения ваших задач, сохраняя при этом разумный код и удобство сопровождения. - person alexw; 15.02.2015
comment
Это гораздо лучший ответ, чем принятый ... Аватар с фейспалмом здесь идеален :-) - person RavenHursT; 14.07.2016

Я очищаю свои пользовательские данные так же, как Раду...

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

  2. Во-вторых, и я редко вижу, как это делается в наши дни, что первая проверка, выполняемая на стороне сервера, — это проверка местоположения, откуда отправляется форма. Разрешив отправку формы только со страницы, которую вы указали в качестве действительного местоположения, вы можете убить сценарий ДО того, как вы прочтете какие-либо данные. Конечно, этого самого по себе недостаточно, так как хороший хакер со своим собственным сервером может «подделать» как домен, так и IP-адрес, чтобы вашему сценарию казалось, что он исходит из действительного местоположения формы.

  3. Далее, и мне даже не нужно говорить об этом, но всегда, и я имею в виду ВСЕГДА, запускайте свои скрипты в режиме заражения. Это заставляет вас не лениться и усердно относиться к шагу номер 4.

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

    И вот чем я отличаюсь от большинства других на этом четвертом шаге, поскольку я очищаю только те пользовательские данные, которые собираюсь ИСПОЛЬЗОВАТЬ, таким образом, который может представлять угрозу безопасности, например, любые системные вызовы, присвоения другим переменным или любая запись для хранения данных. Если я использую данные, введенные пользователем, только для сравнения с данными, которые я сам сохранил в системе (поэтому зная, что мои собственные данные безопасны), то я не беспокоюсь о санации пользовательских данных, поскольку я Я никогда не собираюсь использовать это таким образом, который представляет собой проблему безопасности. Например, возьмем ввод имени пользователя в качестве примера. Я использую введенное пользователем имя пользователя только для проверки его соответствия в моей базе данных, и если это правда, после этого я использую данные из базы данных для выполнения всех других функций, которые я мог бы вызвать в сценарии, зная, что это безопасно , и после этого никогда больше не используйте данные пользователей.

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

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

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

Или, короче говоря, как часто говорила моя мама… «Лучше перестраховаться, чем потом сожалеть».

ОБНОВИТЬ:

Еще одна вещь, которую я делаю в эти дни, это кодирование Base64 всех моих данных, а затем шифрование данных Base64, которые будут находиться в моих базах данных SQL. Для хранения таким образом требуется примерно на треть больше байтов, но, на мой взгляд, преимущества безопасности перевешивают дополнительный размер данных.

person Epiphany    schedule 20.08.2010
comment
Спасибо, что поделился. Мне понравился пункт 2. то есть проверка источника перед отправкой формы. - person Gaurav Sharma; 22.06.2011
comment
Блокировка слепых пользователей — не лучшая практика. - person TRiG; 28.06.2011
comment
Обновление просто сделало его сказочным. - person Your Common Sense; 02.09.2013
comment
Итак, я предполагаю, что режим заражения - это шутка, но не могли бы вы уточнить, что это такое, просто чтобы я понял? - person Funktr0n; 17.04.2014
comment
Я переключу пункт 2. на простой токен, каждая форма, которая может отправлять данные обратно на сервер, должна быть создана с истекающим токеном, а затем прерываться, если токен неверен или истек. Используйте какой-нибудь хороший генератор случайных чисел для токена, который не так просто угадать, как time(). И еще одно, если срок действия токена формы истек, не перезагружайте страницу и не заставляйте пользователя вводить все заново. Плохой UXE — убийца большинства веб-страниц. - person Radu Maris; 10.07.2015
comment
Благодаря тому, что я согласен с вашим редактированием @CommonSenseCode, я откатил его в соответствии с: meta.stackoverflow.com/questions/381780/ - person Script47; 25.03.2019

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

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

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

person Kibbee    schedule 30.08.2008

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

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

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

person cpm    schedule 29.08.2008

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

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

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

person Peter Stone    schedule 29.08.2008

Мое мнение - дезинфицировать пользовательский ввод как можно скорее на стороне клиента и на стороне сервера, я делаю это так

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

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

person Radu Maris    schedule 19.07.2010

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

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

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

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

person Jon Ericson    schedule 29.08.2008
comment
проверить данные пользователя сразу = неправильно. Ваше последнее предложение правильно: и вы никогда не можете предсказать, какие данные будут использоваться для каких целей позже. Вот почему вам нужно дезинфицировать данные по мере их использования, а не при их создании. - person csauve; 30.03.2015
comment
@csauve: О, я не думаю, что вам не следует также проверять данные на работоспособность перед их использованием. Но позвольте спросить вас: если вы собираете данные от пользователя, а позже они оказываются непригодными для использования, как вы предлагаете пользователю исправить проблему? Честно говоря, вопрос на самом деле немного ложная дихотомия. - person Jon Ericson; 31.03.2015
comment
Вы должны проверить наличие непригодных данных в соответствии с вашими бизнес-требованиями, но данные, содержащие специальные символы, не обязательно непригодны для использования. Вам просто нужно закодировать его соответствующим образом для языка, в который он вставляется (т.е. url encode для urls, html encode для html). - person csauve; 01.04.2015

Очистите данные перед их сохранением. Как правило, не следует выполнять ЛЮБЫЕ действия SQL без предварительной очистки ввода. Вы не хотите подвергать себя атаке SQL-инъекций.

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

  1. Выполняйте только действия по изменению SQL, такие как INSERT, UPDATE, DELETE через POST. Никогда не получите.
  2. Убежать от всего.
  3. Если вы ожидаете, что пользовательский ввод будет чем-то, убедитесь, что вы проверили, что это что-то. Например, вы запрашиваете номер, затем убедитесь, что это номер. Используйте проверки.
  4. Используйте фильтры. Очистите ненужные символы.
person mk.    schedule 29.08.2008

Пользователи злые!

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

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

person Martin    schedule 29.08.2008
comment
Мартин, мне кажется, или это сплошные инсинуации? :) - person Aaron; 16.09.2008
comment
Когда я писал это, я не имел в виду, что это так, перечитывая это, я должен согласиться с вами :) - person Martin; 24.11.2008

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

person BrianH    schedule 29.08.2008

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

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

Конечно, это требует большой работы заранее, но если данные важны, то это достойное вложение.

person Dillie-O    schedule 29.08.2008

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

person Sean Chambers    schedule 29.08.2008

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

person Craig    schedule 29.08.2008