Защитное программирование [закрыто]

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

Какой минимальный уровень качества вы всегда применяете к своему коду?

9.08.2008 17:02:56
14 ОТВЕТОВ
РЕШЕНИЕ

В моей работе наш код должен быть высшего качества.
Итак, мы ориентируемся на две основные вещи:

  1. тестирование
  2. Кодовые обзоры

Те приносят домой деньги.

12
31.08.2011 23:00:50

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

0
9.08.2008 17:09:25

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

Другие вещи, такие как хеширование паролей, шифрование строк подключения и т. Д., Также являются стандартом.

С этого момента, это зависит от фактического применения.

К счастью, если вы работаете с фреймворками, такими как .Net, встроена большая защита.

0
9.08.2008 17:47:10

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

0
9.08.2008 17:54:50

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

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

4
23.11.2009 23:51:15
То, что вы описываете, также известно как YAGNI - en.wikipedia.org/wiki/YAGNI
abyx 23.11.2009 23:54:17

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

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

  1. если они находятся в действительном состоянии, что они остаются в действительном состоянии
  2. нет возможности построить их в недопустимом состоянии
  3. При исключительных обстоятельствах они потерпят неудачу настолько изящно, насколько это возможно (часто это чистка и бросок)
0
10.08.2008 00:53:35

По-разному.

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

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

  • минимальные магические числа
  • лучшие имена переменных
  • полностью проверенная и определенная длина массива / строки
  • программирование по контрактным утверждениям
  • проверка нулевого значения
  • исключения (в зависимости от контекста кода)
  • основные пояснительные комментарии
  • доступная документация по использованию (если Perl и т. д.)
0
10.08.2008 08:13:50

Я возьму другое определение защитного программирования, как то, которое Джош Блох отстаивал в Effective Java . В книге он рассказывает о том, как обрабатывать изменяемые объекты, которые вызывающие абоненты передают в ваш код (например, в установщики), и изменяемые объекты, которые вы передаете вызывающим (например, в получатели).

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

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

0
10.08.2008 08:26:46

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

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

  1. Всегда проверяйте данные из внешних источников, пользователей и т. Д.
  2. «Компонент» или структура всегда должны проверять входящие вызовы.

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

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

1
10.08.2008 09:26:45

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

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

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

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

0
10.08.2008 11:27:30

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

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

0
13.08.2008 17:36:12

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

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

На производстве справляйтесь с проблемами максимально изящно. Если что-то действительно является неисправимой ошибкой, обработайте ее и предоставьте эту информацию пользователю.

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

inline const Vector3 Normalize( Vector3arg vec )
{
    const float len = Length(vec);
    ASSERTMSG(len > 0.0f "Invalid Normalization");
    return len == 0.0f ? vec : vec / len;
}
1
13.08.2008 18:15:11
Мы используем аналогичный способ «увеличения» обнаружения проблем в устаревшем коде. Макрос легко добавить, его единственным эффектом является окно сообщения отладки во время тестирования. Это не чудодейственное решение, но оно лучше, чем «return FALSE»; никто никогда не проверяет
paercebal 18.09.2008 13:11:34

Java, подписанные JAR и JAAS.

Java для предотвращения переполнения буфера и взлома указателя / стека.

Не используйте JNI. (Java Native Interface) предоставляет доступ к библиотекам DLL / Shared.

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

JAAS может позволить вашему приложению не доверять никому, даже себе.

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

Есть некоторые накладные расходы для некоторых из этого, но дыры в безопасности исчезают.

0
5.09.2008 05:31:09

Простой ответ: это зависит . Слишком много защитного кодирования может вызвать серьезные проблемы с производительностью.

0
7.09.2009 11:28:38