Безопасное программирование



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

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

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

Терминология

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

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

Secure coding (Безопасное программирование) — методика написания программ, устойчивых к атакам со стороны вредоносных программ и злоумышленников. Безопасное программирование помогает защитить данные пользователя от кражи или порчи. Кроме того, небезопасная программа может предоставить злоумышленнику доступ к управлению сервером или компьютером пользователя; последствия могут быть различны: от отказа в обслуживании одному пользователю до компрометации секретной информации, потери обслуживания или повреждения систем тысяч пользователей.

Важность

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

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

Анализ (ручной или автоматический) и обеспечение безопасности — дорогостоящая процедура, увеличивающая общую стоимость программного продукта. Ранее полное устранение рисков было общей целью обеспечения безопасности. Сегодня признаётся, что устранение всех рисков не является экономически эффективным. Для каждой предлагаемой системы контроля следует провести анализ затрат и выгод. В некоторых случаях преимущества более безопасной системы могут не оправдывать прямых и косвенных издержек. Выгоды включают не только предотвращение денежных потерь; стоит учитывать, например, и репутационные потери. Прямые расходы включают расходы на приобретение и установку данной технологии; косвенные расходы включают снижение производительности системы и дополнительное обучение сотрудников.

Принципы

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

  • работоспособность и полезность (юзабилити, англ. usability);
  • безопасность (англ. security) — возможность защиты от внешних угроз, атак и сохранение работоспособности после их отражения и устранения;
  • надежность (англ. reliability) — предсказуемое, корректное и безотказное поведение в случае некорректных исходных данных;
  • конфиденциальность (англ. privacy) — обеспечение безопасной и корректной работы с конфиденциальной информацией;
  • обеспечение целостности и корректности бизнеса (англ. business integrity) — чёткая организация сопровождения программы, контроль прозрачности, законности, корректности работы пользователя.

Четыре последних качества стали основой Trustworthy computing (TwC) (англ. Trustworthy computing) («Вычисления, заслуживающие доверия») — инициативы корпорации Microsoft, главная задача которой — обратить внимание разработчиков на важность обеспечения указанных требования на каждом из этапов разработки ПО.

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

Классификация и виды уязвимостей

Классификаторы

Использование стандартизованных описаний уязвимостей упрощает работу специалистов по информационной безопасности. В настоящее время существует несколько популярных классификаторов:

  • CVE (Common Vulnerabilities and Exposures) — словарь конкретных уязвимостей конкретных продуктов;
  • CWE (Common Weakness Enumeration) — база данных типов уязвимостей. Основная задача проекта — предоставить описания распространённых видов уязвимостей, способы их предотвращения, обнаружения и исправления;
  • SecurityFocus BID;
  • OSVDB (Open Sourced Vulnerability Database) — «открытая база данных уязвимостей», созданная тремя некоммерческими организациями. Прекратила работу 5 апреля 2016 года. Блог продолжает работать;
  • Secunia — лента уязвимостей известной датской компании Secunia в области компьютерной и сетевой безопасности;
  • IBM ISS X-Force.

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

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

Метрики

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

  • Базовая (англ. base) — характеристики уязвимости, не зависящие от времени и среды исполнения. Служит для описания сложности эксплуатации уязвимости, потенциального ущерба для конфиденциальности, целостности и доступности информации;
  • Временная (англ. temporal) — метрика, учитывающая временной фактор, например, время на исправление уязвимости;
  • Контекстная (англ. environmental) — метрика, учитывающая информацию о среде функционирования программного обеспечения.

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

Виды уязвимостей

Список распространённых ошибок, ставящих под угрозу безопасность современных программ:

  • внедрение SQL-кода (англ. SQL injection);
  • уязвимости, связанные с web-серверами (XSS, XSRF, расщепление HTTP запроса (англ. HTTP response splitting));
  • уязвимости web-клиентов (DOM XSS);
  • переполнение буфера (англ. Buffer Overflow);
  • дефекты форматных строк (англ. Uncontrolled format string);
  • целочисленные переполнения (англ. Integer overflow);
  • некорректная обработка исключений и ошибок;
  • внедрение команд (командная инъекция, англ. Command injection);
  • утечка информации (англ. Information Exposure);
  • ситуация гонки (англ. Race condition);
  • слабое юзабилити (англ. Insufficient Psychological Acceptability);
  • выполнение кода с завышенными привилегиями (англ. Execution with Unnecessary Privileges);
  • хранение незащищенных данных (англ. Protection Mechanism Failure);
  • проблемы мобильного кода (англ. Mobile Code Issues);
  • слабые пароли;
  • слабые случайные числа;
  • неудачный выбор криптографических алгоритмов;
  • использование небезопасных криптографических решений;
  • незащищенный сетевой трафик (англ. Cleartext Transmission of Sensitive Information);
  • неправильное использование PKI (англ. Improper Certificate Validation);
  • доверие к механизму разрешения сетевых имен (англ. Reliance on Reverse DNS Resolution).

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

Защита

Правильной стратегией защиты от ошибок и уязвимостей является их предупреждение и предотвращение. Это требует от разработчика постоянной проверки входных данных. Например, лучший способ защиты от атак переполнения буфера — проверка того, что входные данные не превышают размера буфера, в котором они сохраняются. Данные, предназначенные для отправки в БД требуют проверки для защиты от атаки типа внедрения SQL-кода. Если данные отправляются на web-страницу, то следует их проверять для защиты от XSS. Однако, избыточное число проверок усложняет разработку исходного кода программы и может привести, в свою очередь, к появлению новых ошибок, поэтому следует комбинировать данную стратегию с другими.

Механизмы для защиты от ошибок может предоставлять компилятор или операционная система. Компилятор GCC позволяет с помощью функции _builtin_object_size() получать размер объекта по указателю на этот объект, так что её использование делает процедуру копирования безопаснее. MSVC при использовании флага /RTCs позволяет на этапе компиляции проверить переполнения локальных переменных, использование неинициализированных переменных, повреждение указателя стека, вызванное несоответствием соглашений о вызовах. Использование технологии CRED (C range error detector) и специальных вставок перед защищаемым разделом стека (StackGuard, SSP) частично позволяет обнаруживать и предотвращать атаки, связанные с выходом за границы массива и разрушением стека.

Операционная система также может контролировать процесс исполнения программы. Данная стратегия может быть полезной в случае, если исходный код данной программы неизвестен. Технология ASLR (рандомизация схемы адресного пространства) является функцией безопасности операционных систем, предназначенной для предотвращения запуска произвольного кода. В настоящее время ASLR поддерживается и в Linux, и в Windows. Повышение уровня безопасности достигается применением технологий неисполнимых стеков: W^X, PaX.

Типовыми атаками на web-сервисы являются внедрение SQL-кода, XSS, CSRF, clickjacking. Современные фреймворки помогают разработчикам в создании безопасных web-приложений. Использование готовых решений позволяет не заниматься многочисленными проверками входящих данных: от заголовков HTTP-запросов до их содержания. Также предоставляется более безопасный метод работы с БД — ORM.

Ущерб

Информация об уязвимостях может быть использована злоумышленниками при написании вирусов. Например, один из первых известных сетевых червей (вирус Морриса) в 1988 году использовал такие уязвимости как переполнение буфера в Unix-демоне finger для распространения между машинами. Тогда количество заражённых машин составило порядка 6 тысяч , а экономический ущерб по данным счётной палаты США составил от 10 до 100 млн долларов.

В 2016 компьютерные вирусы причинили мировой экономике ущерб в 450 млрд долларов.

В 2017 ущерб от вируса WannaCry оценили в 1 млрд долларов. Случаи заражения были зафиксированы по меньшей мере в 150 странах. Вирус применял эксплойт EternalBlue, использующий уязвимость в протоколе SMB, связанную с переполнением буфера.