Написание защищённого кода

Рейтинг:   / 3
ПлохоОтлично 

Защищённый код (написание)Задача защиты программного кода от различных уязвимостей - очень важная проблема в современной быстро растущей индустрии IT. XSS, SQL-инъекции, переполнение буффера с последующими получением привилегий - всё это и многое другое следствия ошибок разработчиков, которые, к сожалению, совершают их с каждым днём всё больше и больше. Объясняется это просто: технологии движутся вперёд, объёмы кода сильно растут, а качество мозга людей и соответственно, написанного ими программного кода - не растёт. Или растёт, но не так быстро.

В нынешнее время очень хорошим результатом для гуру-программиста считается 1 серьёзная ошибка на 1000 строк кода. Для примера, в новомодной Windows 8 содержится 7 миллионов строк. Число критических ошибок подсчитать может 9-летний выпускник начальной школы.

Почему же ситуация столь плоха? Что надо делать, чтобы писать защищённый код и ограждаться от множества уязвимостей в собственном ПО? Об этом в сегодняшней статье, основанной на трудах ведущих разработчиков Microsoft М. Ховарда и Дж. ЛеБланка.

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

Безопасность приложений

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

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

Действие №1. Пропаганда идей безопасности на предприятии, пока идея их обеспечения не станет статьёй в бизнес-плане компании. Для этого, естественно, нужно предъявить начальству весомую аргументацию, прямо касающуюся прибыли компании, после чего убедить начальство в том, чтобы оно само обратилось к сотрудникам с выработанным регламентом политики ИБ.

Действие №2. Взять в штат специалиста по ИБ, который будет заниматься контролем за соблюдением политики ИБ, поддерживать/обслуживать/обновлять/адаптировать динамическую систему ИБ, вырабатывать новую политику ИБ (модели угроз и т.д.).

Действие №3. Организация непрерывного обучения штата: обязательность и непрерывность; регулярная рассылка с выявляемыми проблемами и просьба решить эти проблемы тем, в зоне чьей ответственности они находятся; создать ресурс по ИБ в интрасети, пересматривать написанный код с позиции возможных ошибок ИБ и наличия ныне известных и потенциально возможных уязвимостей.

Действие №4. Классификация ошибок систем ИБ. Можно расширить и назвать данный пункт: составление классифицированной модели угроз. Смысл ясен.

Общие принципы проектирования защищённых приложений:

1.      Защита должна ставиться, как неотъемлемая функция создаваемого ПО.

2.      На обеспечение безопасности ПО должно быть отведено достаточно времени.

3.      Обязательно должна быть составлена модель угроз: декомпозиция ПО с выявлением присущих уязвимостей; определение степени опасности и вероятности возникновения каждой уязвимости/опасности; составление матрицы угроз; определение противодействий, а также действий в случае реализации угрозы.

4.      Определение процедуры удаления небезопасных функций и частей в ПО.

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

6.      Разработка тест-планов и периодическая проверка и контроль процесса создания ПО отделом ИБ на каждом этапе разработки по созданным тест-планам, по возможности, - приглашёнными специалистами.

7.      Обязательный контроль безопасности модуля не тем, кто разработал данный модуль.

8.      Безопасность должна обеспечиваться в конфигурации по умолчанию и при развёртывании.

9.      Особый контроль за предоставлением прав на внесение изменений в ПО.

10.  «Площадь уязвимости» (потенциальная) должна быть как можно меньше (всевозможные открытые TCP/UDPпорты, запускаемые и зависимые службы, динамические веб-страницы, части приложения или службы, запускаемые с высокими привилегиями и т.д.).

11.  Должны быть защищены все уровни (независимо друг от друга и от других уровней защиты).

12.  Используйте правило минимальных привилегий (и + грамотно составленный ACL).

13.  Следует вести разработку с учётом аксиомы: внешние системы по умолчанию не защищены.

14.  Разработайте план действий на случай сбоев или отказов.

15.  Не стройте систему безопасности на ограничении информации о ПО.

16.  Разделяйте код и данные (исключение любой смеси данных и JS- или SQL-кода).

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

Общие принципы безопасного кодирования:

1.         Не предоставляйте взломщику никакой информации.

2.         Не позволяйте информации просочиться через заголовки.

3.         Не включайте ничего лишнего в код!

4.         Следите за квотами, буферами и сериализацией.

5.         Используйте стандартные средства операционной системы.

6.         Не рассчитывайте, что пользователи всегда принимают правильные решения: проверяйте все входные данные в широком смысле.

7.         Не размещайте никаких пользовательских файлов в каталоге \Program Files.

8.         Безопасно создавайте временные файлы (GetTempPath, GetTempFileName)

9.         Никаких внутрикорпоративных имен в приложении!

10.     Ведите журналы безопасности в приложении.

11.     Перенос кода, написанного на С/С++, на управляемый язык (C#).

Безопасность написания защищённого кода на конкретных примерах

Поговорим об основных проблемах и принципах программирования, связанных с написанием безопасного приложения:

1.      Переполнение буфера (стека, кучи, переполнение в результате ошибок индексации массивов, переполнение в результате использования некорректной кодировки). Способ лечения: строгая проверка всех входных данных на корректность во всех отношениях, аккуратность при обработке данных; проверка корректности подаваемых на вход strcpy/strlenи т.д. данных; использование параметра компиляции /gs компилятора gcc/VisualС++ .NET.

2.      Использование злоумышленниками ПО или его службы, запущенного/ой с высокими привилегиями (примеров много, и они очевидны). Решение: а) Выясните, какие ресурсы нужны ПО; б) выясните, какие APIиспользует ПО; в) определите, какая требуется учётная запись и какой ей нужен маркер; г) Отладка ошибок, возникающих из-за ограничения привилегий.

3.      Слабые случайные числа. Решение: использовать ГСЧ на основе хороших блочных шифров с полным набором раундов, работающих в режимах CBC, CFBили OFB (хотя допускается и режим ECB). Генерация – только на основании пароля, который в свою очередь должен удовлетворять определённым условиям сложности (в ПО должна быть проверка).

4.      Слабая криптография. Решение: использование по возможности краткосрочных (сеансовых) ключей. Аутентификационные данные должны храниться строго централизованно, а обрабатываться – локально. В случае возникновения задачи обмена ключами по небезопасному каналу – использовать ассиметричную криптографию, передавая таким способом лишь ключи к симметричному шифру. В случае оборота ЭД, использовать механизм ЭЦП.

5.      Универсальная защита конфиденциальных данных. Проблема: её нет. Решение: шифрование данных мощным симметричным алгоритмом (AES, RC6, Blowfish, 3DESи т.д.), хранение пароля в надёжном разделе реестра (в случае несистемного использование – вообще нехранение пароля!), требование ввода пароля, защита списками ACLфайла и раздела реестра.

6.      Опасность входных данных (SQL-injection, XSSи многое другое). Проблема: очевидна. Решение: особое внимание всякого рода регулярным выражениям; строгий контроль корректности и длины входных данных и их фильтрация. Указывайте полные пути в адресах, представленные в канонической форме.

7.      Опасности работы с БД. Решения: а) Использование параметризованных запросов к БД, отсутствие конструирования запросов внутри приложения; жёсткий контроль корректности отправляемых запросов; б) не подключаться к БД от имени system; г) Используйте безопасно хранимые процедуры.

8.      Защита от XSS-атак: а) кодирование выходных данных; б) использование двойных кавычек во всех атрибутах тэга; в) Как можно чаще используйте innerText; г) Используйте только одну кодовую страницу.

Выводы

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

A.S.

Понравилась статья? Хотите читать этот блог?

Ваш e-mail: *

Ваше имя: *

You have no rights to post comments

Вы здесь: Home Технические вопросы Сетевая безопасность История одного пентеста: тяжело ли взломать банк