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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
55
0
14 214
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

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

Ответ принят как подходящий

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

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

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

... или даже пользователь с отключенным js: /

Fluffy 19.07.2010 12:16

Это плохой совет. Вы должны дезинфицировать свои выходы, а не входы.

csauve 30.03.2015 23:45

@csauve правильный. Не уверен, почему это принятый ответ, когда совершенно ясно, что правильным решением здесь является дезинфекция выходных данных. Не пытайтесь «обнаруживать» «плохие» или «злонамеренные» вводы. Такой подход к проблеме оказался бы попыткой реализовать почти бесконечное количество эвристических решений. См. Здесь для получения дополнительной информации: owasp.org/index.php/…

RavenHursT 14.07.2016 07:29

Прочитав вопрос и ответ еще раз, Даниэль может интерпретировать «Санирование» как «Подтвердить». Если вы хотите проверить, что ввод соответствует критериям для поля (т.е. должен быть положительным целым числом), то сделайте это при вводе. Если вы хотите провести дезинфекцию, например, для защиты от вредоносных значений, сделайте это на выходе.

csauve 14.07.2016 21:58

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

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

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

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

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

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

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

Мартин, это только я или это полно намеков? :)

Aaron 16.09.2008 02:54

Когда я писал его, я не имел в виду, что это так, перечитывая его, я должен согласиться с вами :)

Martin 24.11.2008 14:18

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

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

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

Конечно, это требует много работы, но если данные критичны, то это достойное вложение.

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

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

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

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

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

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

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

«проверить данные пользователя прямо сейчас» = неверно. В вашем последнем предложении все правильно: «И вы никогда не можете предсказать, какие данные будут использоваться для каких целей позже». Вот почему вам нужно дезинфицировать свои данные как использовать, а не при их создании.

csauve 30.03.2015 23:49

@csauve: О, я не думаю, что вам не следует использовать данные проверки работоспособности также перед их использованием. Но позвольте мне спросить вас: если вы собираете данные от пользователя, и позже они оказываются непригодными для использования, как вы побудите пользователя исправить проблему? Честно говоря, вопрос действительно в некотором роде ложной дихотомии.

Jon Ericson 31.03.2015 00:04

Вы должны проверить данные непригодный для использования в соответствии с вашим бизнес-требования, но данные, содержащие специальные символы, не обязательно непригодны для использования. Вам просто нужно кодировать его в соответствии с языком, на который он вставляется (например, кодирование URL-адресов для URL-адресов, кодирование html для html).

csauve 01.04.2015 18:31

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ОБНОВИТЬ:

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

Спасибо, что поделился. Мне понравился 2 балл. т.е. проверка источника перед отправкой формы.

Gaurav Sharma 22.06.2011 13:48

Блокировка слепых пользователей - не лучшая практика.

TRiG 28.06.2011 17:43

Обновление сделало это просто потрясающим.

Your Common Sense 02.09.2013 16:52

Так что я предполагаю, что «режим заражения» - это шутка, но не могли бы вы уточнить, что это такое, просто чтобы я понял?

Funktr0n 17.04.2014 12:33

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

Radu Maris 10.07.2015 12:39

Я согласен с вашим редактированием @CommonSenseCode, я откатил его в соответствии с: meta.stackoverflow.com/questions/381780/…

Script47 25.03.2019 17:09

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

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

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

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

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

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

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

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

Читая ответы, я почувствовал сильное желание опубликовать что-то подобное.

cHao 02.09.2013 16:58

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

alexw 15.02.2015 20:55

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

RavenHursT 14.07.2016 07:33

Другие вопросы по теме