Каков правильный способ безопасного ввода веб-формы для различных контекстов?

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

Как уже говорилось, есть несколько вещей, которые нужно учитывать, когда вас беспокоит веб-безопасность. Вот некоторые основные принципы, которые следует учитывать:

  • Избегайте прямого ввода от пользователей, интегрируемых в запросы и переменные.

Таким образом, это означает, что у вас нет чего-то типа $variable = $_POST['user_input'] . Для любой ситуации, подобной этой, вы передаете пользователю слишком много контроля. Если вход влияет на некоторые запросы к базе данных, всегда есть белые списки для проверки ввода пользователя. Если запрос предназначен для имени пользователя, проверьте его на наличие списка хороших имен пользователей. НЕ просто делайте запрос с введенным пользователем вводом.

Одно (возможное) исключение – для строки поиска. В этом случае вам нужно санировать, просто.

  • Избегайте сохранения ввода пользователя без санитарии.

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

  • НИКОГДА не выводить ничего из пользователя в браузер, не снимая его.

Это, наверное, самое важное, что подчеркивали мне консультанты по вопросам безопасности. Вы не можете просто полагаться на дезинфицирующий вход, когда он получен пользователем. Если вы сами не записали результат, всегда убедитесь, что вывод является безобидным, кодируя любые символы HTML или обертывая его тегом <plaintext> . Это простая халатность со стороны разработчика, если пользователь A загружает бит javascript, который вредит другим пользователям, просматривающим эту страницу. Вы лучше спать ночью, зная, что любой пользовательский вывод ничего не может сделать, кроме как текст во всех браузерах.

  • Никогда не позволяйте никому, кроме пользователя, управлять формой.

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

Вышеизложенное не является вопросом санитарии, а проверкой пользователя. Мой последний момент напрямую связан с этой идеей.

  • Избегайте использования файлов cookie для проверки пользователей или проверки роли.

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

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

Еще раз для хорошей меры:

  • Санизировать все входные данные
  • Кодировать весь вывод
  • Подтвердите любой ввод, используемый для выполнения, против строгого белого списка
  • Убедитесь, что вход поступает от фактического пользователя
  • Никогда не делайте проверку на основе роли пользователя или на основе ролей на стороне браузера / пользователя

И никогда не предполагайте, что список одного человека является исчерпывающим или совершенным.

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

Определение «безопасный» настолько различается между разными слоями

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

Также рассмотрите действия, когда обнаружены нарушения.

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

Может, мне не хватает твоего видения? Вы видели что-то, что близко к тому, что вы имеете в виду?

Вы не можете использовать один метод для дезинфекции данных для всех целей, но хороший старт:

  • Использовать Filter_Var для проверки / санирования

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

Примечание. Адреса электронной почты намного сложнее, чем реализация Filter_Var, поэтому Google для правильной работы.

  • Используйте mysql_real_escape_string перед вводом чего-либо в базу данных Mysql

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