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

StackOverflow https://stackoverflow.com/questions/34896

Вопрос

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Изменяйте только действия SQL, такие как INSERT, UPDATE, DELETE - POST. Никогда не ПОЛУЧАЙТЕ.
  • Беги от всего.
  • Если вы ожидаете, что пользовательский ввод будет чем-то, убедитесь, что вы проверите, что это что-то. Например, вы запрашиваете номер, а затем убедитесь, что это номер. Используйте проверки.
  • Используйте фильтры. Уберите нежелательных персонажей.
  • Пользователи злые!

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

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

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

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

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

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

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

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top