Пользователь равен ненадежному. Никогда не доверяйте вводу ненадежного пользователя. Я понимаю. Тем не менее, мне интересно, когда лучше всего дезинфицировать ввод. Например, вы слепо сохраняете пользовательский ввод, а затем очищаете его всякий раз, когда к нему обращаются/используют, или вы немедленно очищаете ввод, а затем сохраняете эту «очищенную» версию? Может быть, есть и другие подходы, о которых я не подумал в дополнение к этим. Я больше склоняюсь к первому методу, потому что к любым данным, полученным в результате пользовательского ввода, следует подходить осторожно, поскольку «очищенные» данные могут по незнанию или случайно быть опасными. В любом случае, какой метод люди считают лучшим и по каким причинам?
Когда лучше всего дезинфицировать пользовательский ввод?
Ответы (14)
Мне нравится очищать его как можно раньше, что означает, что очистка происходит, когда пользователь пытается ввести неверные данные. Если есть текстовое поле для их возраста, и они вводят что-то кроме числа, я не позволяю нажатию клавиши для буквы проходить.
Затем, независимо от того, что читает данные (часто сервер), я проверяю работоспособность, когда читаю данные, просто чтобы убедиться, что ничего не проскальзывает из-за более решительного пользователя (например, ручное редактирование файлов или даже изменение пакетов). !)
Редактировать: В целом, очищайте рано и очищайте каждый раз, когда вы теряете данные из виду даже на секунду (например, «Сохранить файл» -> «Открыть файл»).
К сожалению, почти никто из участников никогда четко не понимает, о чем идет речь. В прямом смысле. Только @Kibbee удалось все исправить.
Эта тема посвящена санитарной обработке. Но правда в том, что такой вещи, как «санитизация общего назначения», о которой все так хотят говорить, просто не существует.
Существует миллион различных носителей, для каждого из которых требуется свое собственное форматирование данных. Более того, даже один определенный носитель требует различного форматирования для своих частей. Скажем, форматирование HTML бесполезно для javascript, встроенного в HTML-страницу. Или форматирование строк бесполезно для чисел в SQL-запросе.
На самом деле, такая «дезинфекция как можно раньше», как предлагается в большинстве ответов, за которые проголосовали, просто невозможна. Так как никто просто не может сказать, в каком конкретном носителе или части носителя будут использоваться данные. Дескать, готовимся защищаться от "sql-инъекций", убегая от всего, что движется. Но упс! - некоторые обязательные поля не были заполнены, и мы должны заполнить данные обратно в форму, а не в базу данных... со всеми добавленными косыми чертами.
С другой стороны, мы старательно избежали всего «ввода пользователем»… но в sql-запросе мы не заключаем его в кавычки, так как это число или идентификатор. И никакая "дезинфекция" нам никогда не помогала.
С третьей стороны - ладно, мы изо всех сил старались обеззаразить ужасный, ненадежный и презираемый "пользовательский ввод"... но в каком-то внутреннем процессе мы использовали эти самые данные безо всякого форматирования (как мы уже старались!) - и упс! получили впрыск второго порядка во всей красе.
Таким образом, с точки зрения использования в реальной жизни, единственным правильным способом было бы
- форматирование, а не какая-то "санитизация"
- непосредственно перед использованием
- по определенным правилам среды
- и даже следуя подправилам, необходимым для разных частей этого носителя.
Я очищаю свои пользовательские данные так же, как Раду...
Первая клиентская сторона использует как регулярные выражения, так и контролирует допустимые символы, вводимые в заданные поля формы, используя javascript или jQuery, привязанные к событиям, таким как onChange или OnBlur, которые удаляют любой запрещенный ввод еще до того, как он может быть отправлен. Однако имейте в виду, что это на самом деле имеет эффект только для информирования этих пользователей о том, что данные также будут проверены на стороне сервера. Это скорее предупреждение, чем реальная защита.
Во-вторых, и я редко вижу, как это делается в наши дни, что первая проверка, выполняемая на стороне сервера, — это проверка местоположения, откуда отправляется форма. Разрешив отправку формы только со страницы, которую вы указали в качестве действительного местоположения, вы можете убить сценарий ДО того, как вы прочтете какие-либо данные. Конечно, этого самого по себе недостаточно, так как хороший хакер со своим собственным сервером может «подделать» как домен, так и IP-адрес, чтобы вашему сценарию казалось, что он исходит из действительного местоположения формы.
Далее, и мне даже не нужно говорить об этом, но всегда, и я имею в виду ВСЕГДА, запускайте свои скрипты в режиме заражения. Это заставляет вас не лениться и усердно относиться к шагу номер 4.
Очистите пользовательские данные как можно скорее, используя правильно сформированные регулярные выражения, соответствующие данным, которые ожидаются от любого заданного поля в форме. Не прибегайте к ярлыкам, таким как печально известный «волшебный рог единорога», чтобы пройти проверку на зараженность... или вы можете просто отключить проверку на зараженность, ради всего хорошего. сделает для вашей безопасности. Это все равно, что дать психопату острый нож, схватить его за горло и сказать: «Ты действительно не причинишь мне вреда, не так ли».
И вот чем я отличаюсь от большинства других на этом четвертом шаге, поскольку я очищаю только те пользовательские данные, которые собираюсь ИСПОЛЬЗОВАТЬ, таким образом, который может представлять угрозу безопасности, например, любые системные вызовы, присвоения другим переменным или любая запись для хранения данных. Если я использую данные, введенные пользователем, только для сравнения с данными, которые я сам сохранил в системе (поэтому зная, что мои собственные данные безопасны), то я не беспокоюсь о санации пользовательских данных, поскольку я Я никогда не собираюсь использовать это таким образом, который представляет собой проблему безопасности. Например, возьмем ввод имени пользователя в качестве примера. Я использую введенное пользователем имя пользователя только для проверки его соответствия в моей базе данных, и если это правда, после этого я использую данные из базы данных для выполнения всех других функций, которые я мог бы вызвать в сценарии, зная, что это безопасно , и после этого никогда больше не используйте данные пользователей.
Наконец, в наши дни необходимо отфильтровать все попытки автоматической отправки роботами с помощью системы «человеческой аутентификации», такой как Captcha. Это достаточно важно в наши дни, поэтому я потратил время на то, чтобы написать свою собственную схему «аутентификации человека», которая использует фотографии и ввод для «человека», чтобы ввести то, что он видит на картинке. Я сделал это, потому что обнаружил, что системы ввода капчи действительно раздражают пользователей (вы можете сказать по их прищуренным глазам от попыток расшифровать искаженные буквы... обычно снова и снова). Это особенно важно для сценариев, использующих SendMail или SMTP для электронной почты, так как они являются фаворитами для ваших голодных спам-ботов.
Короче говоря, я объясню это так, как я объясняю своей жене... ваш сервер похож на популярный ночной клуб, и чем больше у вас вышибал, тем меньше у вас проблем в ночном клубе. У меня есть два вышибалы за дверью (проверка на стороне клиента и аутентификация человека), один вышибала прямо внутри двери (проверка действительного местоположения отправки формы... «Это действительно вы на этом идентификаторе») и еще несколько вышибал в непосредственной близости. близость к двери (запуск режима taint и использование хороших регулярных выражений для проверки пользовательских данных).
Я знаю, что это старый пост, но я счел его достаточно важным для всех, кто может прочитать его после моего визита сюда, чтобы понять, что это не «волшебная пуля», когда дело доходит до безопасности, и это требует всего они работают в сочетании друг с другом, чтобы обеспечить безопасность ваших пользовательских данных. Простое использование одного или двух из этих методов практически бесполезно, так как их сила существует только тогда, когда они работают вместе.
Или, короче говоря, как часто говорила моя мама… «Лучше перестраховаться, чем потом сожалеть».
ОБНОВИТЬ:
Еще одна вещь, которую я делаю в эти дни, это кодирование Base64 всех моих данных, а затем шифрование данных Base64, которые будут находиться в моих базах данных SQL. Для хранения таким образом требуется примерно на треть больше байтов, но, на мой взгляд, преимущества безопасности перевешивают дополнительный размер данных.
Это зависит от того, какую дезинфекцию вы делаете.
Для защиты от SQL-инъекций ничего не делайте с самими данными. Просто используйте подготовленные операторы, и таким образом вам не придется беспокоиться о воздействии на данные, которые ввел пользователь, и о том, что это негативно повлияет на вашу логику. Вам нужно немного очистить, чтобы убедиться, что числа являются числами, а даты — датами, поскольку все является строкой, поскольку она исходит из запроса, но не пытайтесь выполнять какие-либо проверки, чтобы делать такие вещи, как блокировка ключевых слов или что-то еще.
Для защиты от XSS-атак, вероятно, было бы проще исправить данные до их сохранения. Однако, как уже упоминалось, иногда приятно иметь нетронутую копию именно того, что ввел пользователь, потому что, как только вы его измените, он будет потерян навсегда. Очень жаль, что нет надежного способа гарантировать, что ваше приложение выводит только очищенный HTML, так как вы можете гарантировать, что вас не поймают SQL-инъекцией, используя подготовленные запросы.
Самое главное, всегда быть последовательным, когда вы убегаете. Случайная двойная санация — это плохо, а отсутствие дезинфекции — опасно.
Для SQL просто убедитесь, что ваша библиотека доступа к базе данных поддерживает переменные связывания, которые автоматически экранируют значения. Любой, кто вручную объединяет пользовательский ввод со строками SQL, должен знать лучше.
Для HTML я предпочитаю сбежать в самый последний момент. Если вы уничтожите пользовательский ввод, вы никогда не сможете вернуть его, а если он допустит ошибку, он сможет отредактировать и исправить ее позже. Если вы уничтожите их первоначальный ввод, он исчезнет навсегда.
Раннее — это хорошо, определенно до того, как вы попытаетесь разобрать его. Все, что вы собираетесь вывести позже или особенно передать другим компонентам (например, оболочке, SQL и т. д.), должно быть очищено.
Но не переусердствуйте — например, пароли хэшируются перед их сохранением (правильно?). Хэш-функции могут принимать произвольные двоичные данные. И вы никогда не распечатаете пароль (верно?). Так что не анализируйте пароли и не очищайте их.
Кроме того, убедитесь, что вы выполняете очистку от доверенного процесса - JavaScript/что-либо на стороне клиента хуже, чем бесполезная безопасность/целостность. (Однако ранний сбой может обеспечить лучший пользовательский опыт — просто сделайте это в обоих местах.)
Мое мнение - дезинфицировать пользовательский ввод как можно скорее на стороне клиента и на стороне сервера, я делаю это так
- (клиентская сторона), разрешить пользователю вводить в поле только определенные ключи.
- (на стороне клиента), когда пользователь переходит к следующему полю с помощью onblur, проверяет ввод, который он ввел, на соответствие регулярному выражению и замечает пользователя, если что-то не так.
- (на стороне сервера), снова проверьте ввод, если поле должно быть INTEGER, проверьте это (в PHP вы можете использовать is_numeric() ), если поле имеет известный формат, проверьте его на регулярное выражение, все остальные (например, текстовые комментарии), просто убежать от них. Если что-то подозрительно, остановите выполнение скрипта и верните пользователю уведомление о том, что данные, которые он ввел, недействительны.
Если что-то действительно похоже на возможную атаку, сценарий отправляет мне письмо и SMS, чтобы я мог проверить и, возможно, предотвратить это как можно скорее, мне просто нужно проверить журнал, где я регистрирую все пользовательские входы, и шаги, сделанные сценарием перед тем, как принять ввод или отклонить его.
В Perl есть параметр taint, который считает весь пользовательский ввод «испорченным», пока он не будет проверен регулярным выражением. Испорченные данные можно использовать и передавать, но они искажают любые данные, с которыми соприкасаются, пока не очистятся. Например, если пользовательский ввод добавляется к другой строке, новая строка также становится испорченной. По сути, любое выражение, содержащее испорченные значения, выведет испорченный результат.
Испорченные данные могут быть разбросаны по желанию (испорченные данные по мере их поступления), но как только они используются командой, воздействующей на внешний мир, сценарий perl дает сбой. Поэтому, если я использую испорченные данные для создания файла, построения команды оболочки, изменения рабочего каталога и т. д., Perl завершится с ошибкой безопасности.
Я не знаю другого языка, в котором есть что-то вроде "taint", но его использование было очень интересным. Удивительно, как быстро распространяются испорченные данные, если вы не исправите их сразу. Вещи, которые естественны и нормальны для программиста, такие как установка переменной на основе пользовательских данных или открытие файла, кажутся опасными и рискованными при включенном заражении. Таким образом, лучшая стратегия для того, чтобы добиться цели, — это очиститься, как только вы получите какие-то данные извне.
И я подозреваю, что это лучший способ и для других языков: сразу проверять пользовательские данные, чтобы ошибки и дыры в безопасности не распространялись слишком далеко. Кроме того, должно быть проще проверять код на наличие дыр в безопасности, если потенциальные дыры находятся в одном месте. И вы никогда не сможете предсказать, какие данные будут использованы для каких целей позже.
Очистите данные перед их сохранением. Как правило, не следует выполнять ЛЮБЫЕ действия SQL без предварительной очистки ввода. Вы не хотите подвергать себя атаке SQL-инъекций.
Я как бы следую этим основным правилам.
- Выполняйте только действия по изменению SQL, такие как INSERT, UPDATE, DELETE через POST. Никогда не получите.
- Убежать от всего.
- Если вы ожидаете, что пользовательский ввод будет чем-то, убедитесь, что вы проверили, что это что-то. Например, вы запрашиваете номер, затем убедитесь, что это номер. Используйте проверки.
- Используйте фильтры. Очистите ненужные символы.
Пользователи злые!
Ну, возможно, не всегда, но мой подход заключается в том, чтобы всегда немедленно дезинфицировать, чтобы гарантировать, что ничего рискованного не будет рядом с моим бэкэндом.
Дополнительным преимуществом является то, что вы можете предоставить обратную связь пользователю, если вы дезинфицируете точку ввода.
Предположим, что все пользователи являются злонамеренными. Дезинфицируйте все входные данные как можно скорее. Полная остановка.
Я очищаю свои данные прямо перед тем, как обработать их. Мне может понадобиться взять поля «Имя» и «Фамилия» и объединить их в третье поле, которое будет вставлено в базу данных. Я собираюсь дезинфицировать ввод еще до того, как сделаю конкатенацию, чтобы не было никаких ошибок обработки или вставки. Чем скорее, тем лучше. Даже использование Javascript на внешнем интерфейсе (в веб-настройке) идеально, потому что это будет происходить без передачи каких-либо данных на сервер с самого начала.
Страшно то, что вы можете даже начать очищать данные, поступающие из вашей базы данных. Недавний всплеск атак ASPROx SQL Injection, которые имели место, вдвойне смертоносен, потому что он заразит все таблицы базы данных в данной базе данных. Если ваша база данных размещена где-то, где в одной и той же базе данных размещено несколько учетных записей, ваши данные будут повреждены из-за чьей-то ошибки, но теперь вы присоединились к ряду хостинга вредоносных программ для своих посетителей из-за не вашей первоначальной вины. .
Конечно, это требует большой работы заранее, но если данные важны, то это достойное вложение.
Пользовательский ввод всегда следует рассматривать как злонамеренный, прежде чем он попадет на нижние уровни вашего приложения. Всегда обрабатывайте входные данные для очистки как можно скорее, и ни по какой причине не следует сохранять их в вашей базе данных до проверки на наличие злонамеренных намерений.
Я считаю, что его очистка сразу имеет два преимущества. Во-первых, вы можете проверить его и предоставить отзыв пользователю. Во-вторых, вам не нужно беспокоиться об использовании данных в других местах.