Jump to content

Оборонительное программирование

Защитное программирование — это форма защитного проектирования, предназначенная для разработки программ, способных обнаруживать потенциальные нарушения безопасности и принимать заранее определенные меры реагирования. [1] Он обеспечивает непрерывную работу программного обеспечения в непредвиденных обстоятельствах. Практики защитного программирования часто используются там, где высокая доступность , безопасность или защищенность необходима .

Защитное программирование — это подход к улучшению программного обеспечения и исходного кода с точки зрения:

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

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

Безопасное программирование [ править ]

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

int risky_programming(char *input) {
  char str[1000]; 
  
  // ...
  
  strcpy(str, input);  // Copy input.
  
  // ...
}

Функция приведет к неопределенному поведению, если входная длина превышает 1000 символов. Некоторые программисты могут не считать это проблемой, предполагая, что ни один пользователь не будет вводить такой длинный ввод. Эта конкретная ошибка демонстрирует уязвимость, которая позволяет переполнение буфера использовать . Вот решение этого примера:

int secure_programming(char *input) {
  char str[1000+1];  // One more for the null character.

  // ...

  // Copy input without exceeding the length of the destination.
  strncpy(str, input, sizeof(str));

  // If strlen(input) >= sizeof(str) then strncpy won't null terminate. 
  // We counter this by always setting the last character in the buffer to NUL,
  // effectively cropping the string to the maximum length we can handle.
  // One can also decide to explicitly abort the program if strlen(input) is 
  // too long.
  str[sizeof(str) - 1] = '\0';

  // ...
}

программирование Наступательное

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

данных к достоверности Доверие внутренних

Чрезмерно оборонительное программирование
const char* trafficlight_colorname(enum traffic_light_color c) {
    switch (c) {
        case TRAFFICLIGHT_RED:    return "red";
        case TRAFFICLIGHT_YELLOW: return "yellow";
        case TRAFFICLIGHT_GREEN:  return "green";
    }
    return "black"; // To be handled as a dead traffic light.
    // Warning: This last 'return' statement will be dropped by an optimizing
    // compiler if all possible values of 'traffic_light_color' are listed in
    // the previous 'switch' statement...
}
Наступательное программирование
const char* trafficlight_colorname(enum traffic_light_color c) {
    switch (c) {
        case TRAFFICLIGHT_RED:    return "red";
        case TRAFFICLIGHT_YELLOW: return "yellow";
        case TRAFFICLIGHT_GREEN:  return "green";
    }
    assert(0); // Assert that this section is unreachable.
    // Warning: This 'assert' function call will be dropped by an optimizing
    // compiler if all possible values of 'traffic_light_color' are listed in
    // the previous 'switch' statement...
}

Доверие к компонентам программного обеспечения [ править ]

Чрезмерно оборонительное программирование
if (is_legacy_compatible(user_config)) {
    // Strategy: Don't trust that the new code behaves the same
    old_code(user_config);
} else {
    // Fallback: Don't trust that the new code handles the same cases
    if (new_code(user_config) != OK) {
        old_code(user_config);
    }
}
Наступательное программирование
// Expect that the new code has no new bugs
if (new_code(user_config) != OK) {
    // Loudly report and abruptly terminate program to get proper attention
    report_error("Something went very wrong");
    exit(-1);
}

Техники [ править ]

Вот некоторые методы защитного программирования:

Интеллектуальное повторное использование исходного кода [ править ]

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

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

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

Устаревшие проблемы [ править ]

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

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

Многие программные продукты столкнулись с проблемами со старым устаревшим исходным кодом; например:

  • Устаревший код , возможно, не был разработан в рамках инициативы защитного программирования и, следовательно, может быть гораздо более низкого качества, чем недавно разработанный исходный код.
  • Устаревший код мог быть написан и протестирован в условиях, которые больше не применяются. Старые тесты обеспечения качества могут больше не иметь силы.
    • Пример 1. Устаревший код мог быть разработан для ввода ASCII, но теперь ввод имеет формат UTF-8.
    • Пример 2 : устаревший код мог быть скомпилирован и протестирован на 32-битных архитектурах, но при компиляции на 64-битных архитектурах могут возникнуть новые арифметические проблемы (например, неверные тесты подписи, недопустимые приведения типов и т. д.).
    • Пример 3. Унаследованный код может быть предназначен для автономных компьютеров, но становится уязвимым после добавления сетевого подключения.
  • Унаследованный код не пишется с учетом новых проблем. Например, исходный код, написанный в 1990 году, вероятно, будет подвержен множеству уязвимостей, связанных с внедрением кода , поскольку большинство таких проблем в то время не было широко изучено.

Яркие примеры проблемы наследия:

  • BIND 9 , представленный Полом Викси и Дэвидом Конрадом как «BINDv9 — это полная переработка », «Безопасность была ключевым моментом при проектировании», [2] называя безопасность, надежность, масштабируемость и новые протоколы ключевыми проблемами при переписывании старого унаследованного кода.
  • Microsoft Windows страдала от уязвимости метафайла Windows и других эксплойтов, связанных с форматом WMF. Центр реагирования безопасности Microsoft описывает функции WMF как «Примерно в 1990 году была добавлена ​​поддержка WMF... Это было другое время в сфере безопасности... всем нам полностью доверяли» . [3] не разрабатывается в рамках инициатив по безопасности Microsoft.
  • Oracle борется с устаревшими проблемами, такими как старый исходный код, написанный без решения проблем внедрения SQL и повышения привилегий , что приводит к множеству уязвимостей безопасности, на исправление которых потребовалось время, а также к появлению неполных исправлений. Это вызвало резкую критику со стороны таких экспертов по безопасности, как Дэвид Личфилд , Александр Корнбраст , Сезар Серрудо . [4] [5] [6] Дополнительная критика заключается в том, что установки по умолчанию (в основном наследие старых версий) не соответствуют их собственным рекомендациям по безопасности, таким как Контрольный список безопасности базы данных Oracle, который трудно изменить, поскольку многим приложениям для правильной работы требуются менее безопасные устаревшие настройки.

Канонизация [ править ]

Злоумышленники, скорее всего, придумают новые способы представления неверных данных. Например, если программа попытается запретить доступ к файлу «/etc/ passwd », взломщик может передать другой вариант имени этого файла, например «/etc/./passwd». Библиотеки канонизации можно использовать, чтобы избежать ошибок из-за неканонического ввода.

Низкая толерантность к «потенциальным» ошибкам [ править ]

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

Другие советы по защите вашего кода [ править ]

  • Одной из наиболее распространенных проблем является неконтролируемое использование структур постоянного размера или предварительно выделенных структур для данных динамического размера. [ нужна ссылка ] например, входные данные для программы ( проблема переполнения буфера ). Это особенно характерно для строковых данных в C. [ нужна ссылка ] . Функции библиотеки C, такие как gets никогда не следует использовать, поскольку максимальный размер входного буфера не передается в качестве аргумента. Функции библиотеки C, такие как scanf может использоваться безопасно, но требует, чтобы программист позаботился о выборе строк безопасного формата, очистив их перед использованием.
  • Шифруйте/аутентифицируйте все важные данные, передаваемые по сети. Не пытайтесь реализовать собственную схему шифрования, вместо этого используйте проверенную . Проверка сообщений с помощью CRC или аналогичной технологии также поможет защитить данные, передаваемые по сети.

Три правила безопасности данных [ править ]

  • Все данные важны, пока не доказано обратное.
  • Все данные испорчены, пока не доказано обратное.
  • Любой код небезопасен, пока не доказано обратное.

Эти три правила безопасности данных описывают, как обращаться с любыми данными, полученными из внутренних или внешних источников:

Все данные важны, пока не доказано обратное . Это означает, что все данные должны быть проверены как мусор перед уничтожением.

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

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

Дополнительная информация [ править ]

  • Если данные необходимо проверить на правильность, убедитесь, что они верны, а не неверны.
  • Проектирование по договору
  • Утверждения (также называемые ассертивным программированием )
  • Предпочитайте исключения кодам возврата
    • Вообще говоря, предпочтительнее [ по мнению кого? ] выдавать сообщения об исключениях, которые обеспечивают выполнение части вашего API контракта и помогают разработчику вместо возврата значений кодов ошибок, которые не указывают на то, где произошло исключение или как выглядел стек программы. Улучшенное ведение журнала и обработка исключений повысят надежность и безопасность вашего программное обеспечение [ нужна ссылка ] , минимизируя при этом стресс разработчика [ нужна ссылка ] .

См. также [ править ]

Ссылки [ править ]

  1. ^ Буланже, Жан-Луи (01 января 2016 г.), Буланже, Жан-Луи (редактор), «6. Методика управления безопасностью программного обеспечения» , Сертифицированные программные приложения 1 , Elsevier, стр. 125–156, ISBN  978-1-78548-117-8 , получено 2 сентября 2022 г.
  2. ^ «Архив fogo: Пол Викси и Дэвид Конрад о BINDv9 и интернет-безопасности, Джеральд Оскобойни < [электронная почта защищена] . впечатляющий.нет . Проверено 27 октября 2018 г.
  3. ^ «Глядя на проблему WMF, как она туда попала?» . МСРК . Архивировано из оригинала 24 марта 2006 г. Проверено 27 октября 2018 г.
  4. ^ Личфилд, Дэвид. «Bugtraq: Oracle, где патчи???» . сайт seclists.org . Проверено 27 октября 2018 г.
  5. ^ Александр, Корнбруст. «Bugtraq: RE: Oracle, где патчи???» . сайт seclists.org . Проверено 27 октября 2018 г.
  6. ^ Серрудо, Сезар. «Bugtraq: Re: [Полное раскрытие] RE: Oracle, где патчи???» . сайт seclists.org . Проверено 27 октября 2018 г.

Внешние ссылки [ править ]

Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: ffec944ef8d4674c52c3d5cbaed96401__1702410720
URL1:https://arc.ask3.ru/arc/aa/ff/01/ffec944ef8d4674c52c3d5cbaed96401.html
Заголовок, (Title) документа по адресу, URL1:
Defensive programming - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)