70% проблем с безопасностью в Chromium вызваны ошибками при работе с памятью

Разработчики проекта Chromium проанализировали 912 опасных и критичкских уязвимостей, выявленных в стабильных выпусках Chrome, и пришли к выводу, что 70% из них были вызваны небезопасной работой с памятью (ошибками, при работе с указателями в коде на C/C++. Половина из данных пробоем (36.1%) вызвана обращениями к буферу, после освобождения связанной с ним памяти (use-after-free).

При проектировании Chromium было изначально заложено, что код может включать в себя ошибки, поэтому большая ставка делалась на применение sandbox-изоляции для ограничения последствий проявления уязвимостей. В настоящее время возможности применения данной технологии достигли предела своих возможностей и дальнейшее дробление нецелесообразно с точки зрения потребления ресурсов. Для поддержания безопасности кодовой базы Google применяет «правило двух«, в соответствии с которым любой добавляемый код должен подпадать не больше, чем под два условия из трёх: работа с непроверенными входными данными, использование небезопасного языка программирования (C/C++) и выполнение с повышенными привилегиями. Из этого правила следует, что код для обработки внешних данных должен либо быть урезан до минимальных привилегий (изолирован), либо быть написан на безопасном языке программирования.

Для дальнейшего усиления защищённости кодовой базы запущен проект по предотвращению появления ошибок работы с памятью в кодовой базе. Выделяется три основных подхода: создание библиотек С++ с функциями для безопасной работы с памятью и расширение области применения сборщика мусора, применение аппаратных механизмов защиты MTE (Memory Tagging Extension и прекращения работы с голыми указателями на С++) и написание компонентов на языках, обеспечивающих безопасную работу с памятью (Java, Kotlin, JavaScript, Rust, Swift).

Ожидается, что работа будет сосредоточена в двух направлениях:

  • Значительное изменение процесса разработки на С++, не исключающее негативного влияния на производительность (дополнительные проверки границ и сборка мусора). Вместо raw-указателей предлагается использовать в коде тип MiraclePtr, позволяющий свести эксплуатируемые ошибки класса use-after-free к не представляющим угрозу безопасности крахам, без ощутимого негативного влияния на производительность, потребление памяти и стабильность.
  • Применение языков, рассчитанных на выполнение проверок безопасности работы с памятью во время компиляции (позволит исключить негативное влияние на производительность за счёт избавления от осуществления подобных проверок во время выполнения кода, но приведёт к дополнительным расходам на организацию взаимодействия кода на новым языке с кодом на С++).

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

Источник: http://www.opennet.ru/opennews/art.shtml?num=53019