[Перевод] Правила безопасного программирования на С: прошлое, настоящее и будущее

857a30a825dd4860b05d456b82a89717.jpgLuxoft Training предлагает вам познакомиться с переводом статьи "C Secure Coding Rules: Past, Present, and Future" Роберта С. Сикорда, профессора института программной инженерии (SEI) Карнеги-Меллон, автора книг «The CERT C Coding Standard, Second Edition» и «Secure Coding in C and C++, Second Edition».

Инициатива CERT по безопасному программированию работает над стандартами написания кода с 2006 г. Эксперт программирования Робет С. Сикорд, автор книги «Безопасное программирование на С и С++» рассказывает о своем вкладе в этот проект, о стандарте по безопасному кодированию на языке С (ISO/IEC TS 17961) и рассуждает о будущем этих стандартов.

От автора Secure Coding in C and C++, 2nd Edition

Разработка ПО по безопасным стандартам кодирования – хорошая практика, а в последнее время и требование. Раздел 933 акта авторизации национальной обороны США (NDAA) от 2013 г. «Совершенствование программного обеспечения, закупаемого Министерством обороны» требует свидетельств того, что организации, разрабатывающие ПО для государственного сектора придерживаются стандартов безопасного кодирования, принятых в Министерстве обороны (DoD), во время разработки, обновления и сопровождения ПО, а также во время инспектирования и оценки.

Руководство по технической реализации систем безопасности (STIG) для приложений и процесса разработки постоянно указывается в качестве требования в запросах на подачу конкурсных предложений (RFPs) Министерства обороны. Раздел 2.1.5, «Стандарты кодирования» STIG требует от Руководителя проекта «контроль того, что команда разработки следует ряду стандартов написания кода».

Однако ряд проблем затрудняет возможность соблюдения этих требований:

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

В течение почти десяти лет Инициатива по безопасному кодированию при CERT работала над решением этих проблем, создавая руководство по написанию безопасного кода для разработчиков. CERT также ведет активную работу с ISO/IEC в области утверждения базового набора требований к поставщикам анализаторов и компиляторов языка C, которые хотели бы диагностировать небезопасный код за пределами стандартов этого языка. CERT также разрабатывает набор тестов для оценки соответствия этим требованиям.

Стандарты безопасного кодирования CERT широко применяются в отрасли. На конференции SecCon в октябре 2011 Cisco Systems объявила о принятии стандарта CERT по безопасному кодированию на C в качестве базового стандарта разработки продуктов. Недавно Oracle интегрировала все стандарты безопасного кодирования CERT в свои стандарты безопасности. Это стало еще одним шагом в долгом сотрудничестве CERT и Oracle: обе организации уже работали над разработкой стандартов безопасного кодирования для Java.

Я присоединился к Комитету по стандартизации языка С (официальное название ISO/IEC JTC1/SC22/WG14) во время работы над первым изданием книги «Безопасное программирование на C и C++». В то время WG14 работала над созданием документа «C Library Security TR 24731», который должен был стандартизировать функции «_s», разрабатываемые Microsoft. Я обменялся несколькими сообщениями с Рэнди Мейерсом, который возглавлял J11 (ставшей затем PL22.11), по поводу странного поведения функции gets_s(), которая не считывала знак окончания строки. В итоге, весной 2005 г. я поехал на совещание WG14 в Лиллехаммер (Норвегия) и с тех самых пор CERT связана с Комитетом по стандартизации языка С.

ПРИМЕЧАНИЕ
Рабочая группа PL22.11 отвечает за техническую разработку стандарта для языка программирования С. Это техническая консультативная группа США при ISO/IEC JTC 1 SC22/WG14.

На совещании WG14 весной 2006 г. в Берлине, доктор Томас Плум предложил мне идею создания стандартов безопасного программирования CERT. Единственным аналогом этого на тот момент был MISRA C: Руководство по использованию языка С в критических системах (2004). Однако это руководство предназначалось для тех систем, где безопасность стоит на первом месте, требования к которым существенно отличаются от требований к большинству систем, и препятствовало использованию возможностей языка, одобренных ISO/IEC 9899:1999.

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

Стандарт безопасного кодирования CERT разрабатывался на CERT Secure Coding wiki по принципу комьюнити-разработки. Эксперты комьюнити, включая членов Комитета стандартизации С WG14 были приглашены в проект и наделены правами редактирования в вики. Члены комьюнити могут зарегистрироваться в вики и оставлять комментарии по конкретным стандартам кодирования и отдельным правилам. Рецензенты, оставлявшие высококачественные комментарии часто получали редакторские привилегии и уже напрямую участвовали в разработке стандартов программирования. На сегодняшний день в вики CERT Secure Coding насчитывается 1374 автора.

Процесс комьюнити-разработки имеет множество преимуществ. Наиболее важным является то, что он позволяет широкой группе экспертов сформировать единое мнение по содержанию правил. Основным недостатком такого вида разработки стандартов кодирования является то, что содержание стандарта находится в процессе постоянного изменения. Это очень здорово, если вам нужна наиболее актуальная информация, и вы отдаете себе отчет в том, что последнее изменение еще не было окончательно проверено. Однако многие компании по разработке ПО требуют статический набор правил и рекомендаций, которые могут использоваться в качестве требований в их процессах разработки. С этой целью мы создали снимок состояния стандарта через два с половиной года после начала комьюнити-разработки и выпустили его отдельным изданием, The CERT C Secure Coding Standard (Addison-Wesley, 2008). Книга покрывает версию 1.0 стандарта. С выходом рукописи в июне 2008 года, версия 1.0 (книги) и вики-версия стандарта начали расходится.

Руководство CERT C Secure Coding было впервые рассмотрено группой WG14 на встрече в Лондоне в апреле 2007 года, а затем еще раз в Коне (Гавайи) в августе 2007 года.

Вопрос, стоит ли PL22.11 представить Стандарт CERT по безопасному кодированию на С группе WG14 для публикации в качестве технического отчета 2-го или 3-го типа, обсуждался на встрече J11/U.S. TAG 15 апреля 2008 года, что отражено в протоколе совещания. Было проведено предварительное голосование по вопросу «У кого есть время поработать над этим проектом?», с распределением голосов 4 к 12. Было решено не принимать никаких действий. Позже нам сказали, что, несмотря на то, что Стандарт по безопасному кодированию на С и является серьезным набором рекомендаций, разработанных с помощью многих технических экспертов WG14, сама WG14 не занимается выдачей рекомендаций разработчикам. Однако WG14 определенно занималась разработкой нормативных требований к инструментам, таким как компиляторы.

Вооруженные этим знанием, мы предложили WG14 создать рабочую группу для изучения проблемы создания руководства по безопасному кодированию на языке С. Первая встреча рабочей группы состоялась 27 октября 2009 года. Томас Плум выступил в роли председателя, а я был избран на роль редактора проекта. CERT внесла набор релизуемых правил по безопасному кодированию на С в ISO/IEC для использовании в процессе стандартизации.

Дэвид Китон, действующий председатель PL22.11, впоследствии заменил Тома на его посту. Среди участников группы были поставщики анализаторов, такие как Coverity, Fortify, GammaTech, Gimpel, Klocwork и LDRA; эксперты по безопасности; эксперты по языку и пользователи. Наконец вопрос о разработке и публикации стандарта безопасного кодирования на языке С ISO/IEC TS 17961 был поставлен в план действий на совещании WG14 в марте 2012, и рабочая группа прекратила свою работу. Позже к редакторской коллегии присоединился Роберто Багнара, работавший в Лаборатории прикладных формальных методов Пармского университета и компании BUGSENG.

Цель ISO/IEC TS 17961 – закрепить базовый набор требований для анализаторов, включая средства статического анализа, и поставщиков компиляторов языка С, которые хотели бы проводить диагностику небезопасного кода за пределами стандартов языка С. Все правила реализуются через статический анализ. Критерием для выбора правил является то, что анализаторы, реализующие эти правила, должны эффективно распознавать ошибки в безопасности кода без генерации избыточного числа ложных результатов.

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

Стандарт ISO/IEC TS 17961 предписывает правила безопасного кодирования на языке С и приводит примеры кода. Стандарт не описывает механизм применения этих правил или конкретного стиля кодирования. Каждое правило сопровождается примерами кода. Примеры плохого кода демонстрируют языковые конструкции, обладающие потенциальными изъянами безопасности; такие примеры кода должны вылавливаться стандартизированными анализаторами. Примеры образцового кода не должны вылавливаться анализаторами.

В следующей таблице показана связь ISO/IEC TS 17961 с другими стандартами. Из всех перечисленных публикаций, только ISO/IEC TS 17961 предназначен для анализаторов, а не разработчиков.

Стандарт кодирования Стандарт С Стандарт безопасности Стандарт надежности Международный стандарт Весь язык
CWE Нет/все Да Нет Нет N/A
MISRA C2 C89 Нет Да Нет Нет
MISRA C3 С99 Нет Да Нет Нет
CERT C99 С99 Да Нет Нет Да
CERT C11 С11 Да Нет Нет Да
ISO/IEC TS 17961 С11 Да Нет Да Да


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

Accessing freed  memory in function abc, file xyz.c, line nnn.


ISO/IEC TS 17961 не требует от анализатора выдавать диагностику для ошибок в синтаксисе или для ограничений Стандарта на язык С. Речь идет только об исходном коде, который может быть прочитан анализатором. На бинарные библиотеки и обращения к ним данные правила не распространяются.

Интересный аспект технической спецификации – переносимость допущений, известная также под именем «Правило Сан-Франциско», поскольку эти допущения были сформулированы на встрече, организованной компанией Coverity в их главном офисе. «Правило Сан-Франциско» гласит, что отвечающий стандарту анализатор должен распознавать случаи нарушения предписаний по крайней мере для одной реализации С, но не обязан распознавать нарушения правила, если результат документируется для конечной реализации и не создаёт изъянов в безопасности. Различия в качестве реализации позволяют анализатору выдавать диагностику для проблем переносимости. Например, для следующего фрагмента программы:

long i;  printf("i = %d", i); 


ISO/IEC TS 17961:2013(E) «Информационные технологии. Языки программирования, их окружение и системы программных интерфейсов. Правила безопасного кодирования C» был официально опубликован в ноябре 2013 и доступен для покупки в магазине стандартов ISO.

Помимо прочего, книга The CERTC Coding Standard, Second Edition была исправлена для соответствия с ISO/IEC TS 17961. Хотя эти документы предназначены для разных аудиторий, согласованность между документами должна помочь разработчикам использовать анализаторы, отвечающие ISO/IEC TS 17961, вылавливать нарушения правил данного стандарта кодирования.

CERT также разработала Secure Coding Validation Suite, набор тестов для валидации правил, установленных ISO/IEC TS 17961. Эти тесты основаны на примерах данной технической спецификации и распространяются по лицензии BSD.


Разработчики статических анализаторов работают над созданием анализаторов, отвечающих требованиям ISO/IEC TS 17961. Пока ведутся эти работы, мы будет продолжать оценивать эффективность технической спецификации и попытаемся понять: нужно ли подготовить вторую редакцию, которая либо устранит недостатки опубликованной версии, либо пополнится новыми правилами, например, касательно нестандартного поведения, связанного с использованием функций многопоточности, представленных в версии C11.

Поскольку язык С и наши знания о его безопасном использовании постоянно развиваются, SEI продолжит комьюнити-разработку SEI CERT C Coding Standard в вики по безопасному кодированию. Эти изменения позднее могут быть включены в будущий официальный релиз этого стандарта. Новая версия будет отправлена в Addison-Wiley для публикации.


Выражаю признательность рецензентам, которые сыграли большую роль в этой истории: Дэвиду Китону, Томасу Плуму, и Джону Бенито.

Published with permission from Pearson Education.

26 и 27 ноября Luxoft Training приглашает вас на мастер-класс Роберта С. Сикорда, посвященный безопасному программированию на языках С и С++.

© Habrahabr.ru