Проверка правильности ввода данных - где? Как много? [закрыто]

28

Проверка ввода данных всегда была для меня довольно внутренней борьбой.

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

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

Подводя итог, это мои рекомендации (представлены в трехуровневом стиле веб-приложения) с краткими пояснениями:

  • Клиентская часть 1-го уровня (браузер): минимальная проверка, только неизменные правила (обязательное поле электронной почты, необходимо выбрать один элемент и т. П.); реже используется дополнительная проверка, например, «от 6 до 20 символов», так как это увеличивает объем работ по обслуживанию изменений (может быть добавлено после стабилизации бизнес-кода);

  • Серверная часть 1-го уровня (обработка веб-коммуникации, «контроллеры»): у меня нет правила для этого, но я считаю, что здесь должны обрабатываться только ошибки манипулирования данными и сборки / синтаксического анализа (поле дня рождения недопустимо); добавление дополнительной проверки здесь легко делает этот процесс действительно скучным;

  • 2-й уровень (бизнес-уровень): надежная проверка, не менее; формат входных данных, диапазоны, значения, внутренняя проверка состояния, нельзя ли вызывать метод в любое время, пользовательские роли / разрешения и т. д .; используйте как можно меньше пользовательских вводимых данных, при необходимости извлеките их снова из базы данных; если мы также рассматриваем полученные данные базы данных как входные данные, я проверю их только в том случае, если известно, что некоторые конкретные данные ненадежны или достаточно повреждены в БД - строгая типизация выполняет большую часть работы здесь, IMHO;

  • 3-й уровень (уровень данных / DAL / DAO): никогда не считалось, что здесь требуется много проверки, так как только бизнес-уровень должен получить доступ к данным (возможно, в некоторых случаях может быть проверка, например, «param2 не должен быть нулевым, если param1 истинно»); заметьте, однако, что когда я имею в виду «здесь», я имею в виду «код, который обращается к базе данных» или «методы выполнения SQL», сама база данных полностью противоположна;

  • база данных (модель данных): должна быть продуманной, сильной и самодостаточной, чтобы максимально избежать некорректных и поврежденных данных в БД, с хорошими первичными ключами, внешними ключами, ограничениями, типом данных / длиной / размером / точность и т. д. - я оставляю триггеры из-за этого, так как у них есть свое личное обсуждение.

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

так что ты думаешь об этом? Противоположные мнения? У вас есть другие процедуры? Ссылка на такую ​​тему? Любой вклад действителен.

Примечание: если вы думаете о способе работы Java, наше приложение основано на Spring с Spring MVC и MyBatis (производительность и плохая модель базы данных исключают решения ORM); Я планирую добавить Spring Security в качестве нашего поставщика безопасности плюс JSR 303 (Hibernate Validator?)

Благодарность!


Изменить: некоторые дополнительные разъяснения на 3-м слое.

mdrg
источник
Мой совет - изучить, как работает Hibernate Validator. Я не нашел JSR 303 полезным для проверки правильности при сохранении, в то время как некоторые из моих правил нужно было применять задолго до сохранения, поскольку у меня были бизнес-правила, основанные на базовой проверке. На мой взгляд, это работает для очень закрытой модели; возможно я использовал это неправильно, но я никогда не находил никого с опытом, отличным от моего.
Винит Рейнольдс
@ Vineet Reynolds Я уже использовал его для проверки формы в Spring MVC, это действительно отличная комбинация. Я получаю проверку на стороне сервера с мелкозернистыми сообщениями без особых усилий, соответствующая ошибка отображается для пользователя. Я все еще тестирую его целиком на объектах на стороне сервера, не уверенный в преимуществах. Взгляните на этот пример поста, вот как я его использовал: codemunchies.com/2010/07/…
mdrg
2
поставить слишком много проверки. Все, где эти чертовы пользовательские вводы @ #! ! @@!
Чани

Ответы:

17

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

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

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

ChrisF
источник
2
+1 абсолютно. Я собирался сказать то же самое о ASP.NET MVC, но вы меня опередили. :) На самом деле нам нужна только проверка на месте, чтобы убедиться, что система остается в действительном состоянии. Остальная часть валидации, например на стороне клиента, предназначена для повышения удобства использования и потери времени для пользователя, поэтому это должно быть в центре внимания. Согласованность является ключевым.
Райан Хейс
2
Что касается «туда-обратно», я не вижу проблем, если страница будет перезагружена с правильными сообщениями об ошибках и все поля заполнены тем, что вы ввели ранее (большинство интерфейсов не соответствуют этой последней детали). Если для возврата к ошибкам требуется слишком много времени, то это кандидат на дополнительную проверку на стороне клиента.
mdrg
И конечно, если проверка может быть легко воспроизведена во всем приложении, нет причин тратить это впустую. На стороне сервера это легко, но на стороне клиента, без таких инструментов проверки, как тот, который вы упомянули, это очень расстраивает (т. Е. Написание большого количества кода проверки JS, такого же, как тот, который вы написали на сервере) ,
mdrg
10

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

  • Представление / UI
    • простая проверка ввода
    • не продолжать, если ввод в неправильном формате
    • клиентские запросы "gate" к серверу сокращают количество обращений, повышают удобство использования и уменьшают пропускную способность и время
  • логика
    • бизнес логика и авторизация
    • не позволяйте пользователям делать то, что им запрещено делать
    • обрабатывать «производные» свойства и состояние здесь (вещи, которые будут денормализованы в базе данных)
  • Данные
    • необходимый уровень целостности данных
    • категорически отказываться хранить любое барахло
    • сама БД применяет форматы данных (int, date и т. д.)
    • использовать ограничения базы данных для обеспечения правильных отношений

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

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

Джон Кромарти
источник
Я посмотрю на носорога. Если он может каким-либо образом интегрироваться с валидацией форм Spring MVC, это намного лучше.
mdrg
8

• 3-й уровень (уровень данных / DAL / DAO): никогда не предполагалось, что здесь требуется много проверки, поскольку предполагается, что только бизнес-уровень должен получить доступ к данным (возможно, проверка возможна в некоторых случаях, например, «param2 не должен быть нулевым, если param1 истинно») ,

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

Он говорит это лучше, чем я: http://softarch.97things.oreilly.com/wiki/index.php/Database_as_a_Fortress

HLGEM
источник
Я согласен с самой последней частью этой статьи, думаю, я не прояснил себя в этой части. Я обновил вопрос с более подробной информацией. Благодарность!
mdrg
2

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

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

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

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

mattnz
источник
1

Два коротких общих правила проверки:

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

Если вы собираетесь делать с данными что-то еще (принимать решения, делать математические операции, сохранять их и т. Д.), Проверяйте их.

Blrfl
источник