Агентство CISA опубликовало исследованиес анализом 172 ключевых Open Source проектов на предмет уязвимости к ошибкам памяти.
Языки программирования, безопасные для памяти, созданы для предотвращения распространённых ошибок, связанных с памятью, таких как переполнения буфера (buffer overflow), использование после освобождения памяти (use-after-free, UAF) и другие виды повреждений памяти (” data-html=”true” data-original-title=”Memory corruption” >memory corruption). Такие языки автоматически управляют памятью, вместо того чтобы полагаться на программиста для реализации механизмов безопасного выделения и освобождения памяти.
Современным примером такой системы является проверка заимствований в языке Rust, устраняющая гонки данных (Data Race). Другие языки, такие как Golang, Java, C# и Python, управляют памятью через сборку мусора (” data-html=”true” data-original-title=”Garbage Collection” >Garbage Collection), автоматически высвобождая освободившуюся память для предотвращения её эксплуатации.
Языки, небезопасные для памяти, не предоставляют встроенных механизмов управления памятью, возлагая эту ответственность на разработчика и увеличивая вероятность ошибок. Примерами таких языков являются C, C++, Objective-C, Assembly, Cython и D.
Отчёт CISA представляет исследование 172 широко используемых проектов с открытым исходным кодом, из которых более половины содержат небезопасный для памяти код. Основные выводы отчёта таковы:
- 52% критически важных проектов с открытым исходным кодом содержат код, написанный на небезопасных для памяти языках;
- 55% от общего числа строк кода (LoC) в этих проектах написаны на небезопасных для памяти языках;
- Крупнейшие проекты в непропорциональной мере написаны на небезопасных для памяти языках;
- Из 10 крупнейших проектов по общему количеству строк кода, каждый имеет долю небезопасного для памяти кода выше 26%;
- Медианная доля небезопасного для памяти кода в крупных проектах составляет 62,5%, причём в 4 проектах показатель превышает 94%;
- Даже проекты, написанные на безопасных для памяти языках, часто зависят от компонентов, написанных на небезопасных для памяти языках.
Некоторые из исследованных проектов, включают Linux (коэффициент небезопасного кода 95%), Tor (93%), Chromium (51%), MySQL Server (84%), glibc (85%), Redis (85%), SystemD (65%) и Electron (47%).
Краткое изложение результатов
CISA отмечает, что разработчики ПО сталкиваются со множеством вызовов, которые часто заставляют их использовать небезопасные для памяти языки, такие как ограничения ресурсов и требования к производительности. Это особенно актуально при реализации низкоуровневых функций, таких как работа с сетями, криптография и функции операционных систем.
В отчёте поясняется, что многие критически важные проекты частично написаны на небезопасных для памяти языках, а ограниченный анализ зависимостей показывает, что проекты наследуют код, написанный на небезопасных для памяти языках, через зависимости.
CISA также подчёркивает проблему отключения функций безопасности памяти разработчиками, либо по ошибке, либо намеренно, чтобы соответствовать определённым требованиям, что создаёт риски даже при использовании теоретически более безопасных компонентов.
CISA рекомендует разработчикам:
- писать новый код на безопасных для памяти языках – Rust, Java и Go;
- переводить существующие проекты, особенно критически важные компоненты, на указанные языки;
- следовать практикам безопасного кодирования;
- тщательно управлять и проверять зависимости;
- проводить непрерывное тестирование, включая статический и динамический анализ;
- проводить фаззинг для выявления и устранения проблем безопасности памяти.