213
0
0
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
Назад

Безопасность и open source

Время чтения 4 минуты
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники
213
0
0
Нет времени читать?
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники

Всем привет, на связи Андрей Фёдоров. Продолжаю разбирать, что же происходит в open source. В прошлой статье я рассматривал особенности лицензирования, в этой заметке поизучаем тему общей безопасности.

Принципы разработки безопасного кода уже давно более-менее формализованы индустрией — например, Microsoft SDL, большое количество наработок в плане практик и инструментов DevSecOps. Но всё же open source оказался далек от требований по безопасности, выдвигаемых бизнесом. Как так получилось?

Безопасность и open source

Почему open source считается небезопасным до сих пор

Долгое время одной из самых популярных причин использовать open source был принцип «тысячи глаз», в общем смысле предполагавший, что если что-то лежит в открытом доступе, то уязвимости обязательно заметят и, если всё пойдет хорошо, исправят. 

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

Даже учитывая всё это, разработчики до сих пор используют open source в своих проектах, часто не задумываясь о безопасности. Они по умолчанию считают, что авторы не зловредны, а код даже случайно не был изменен так, что повредит безопасности. Это maximum trust — принцип, противоположный тому, что продвигают апологеты информационной безопасности под названием zero trust. 

Оправданы ли сомнения в безопасности open source 

Open source действительно вызывал и вызывает опасения и неопределенность насчет безопасности. Популярный аргумент, которым пользовались и пользуются корпоративные пресейлы в аргументации против «открытых» аналогов, — это то, что в open source может контрибьютить любой человек, а в проприетарном ПО есть процессы и ответственность, поэтому оно безопаснее. Эта логика не выдерживает проверки реальностью и временем — как в утверждении «проприетарное ПО безопаснее, чем не проприетарное», так и «open source небезопасен, потому что открыт к контрибьюту любого человека». 

Принцип «тысячи глаз», несмотря на все ситуации, в которых тысячи глаз пропустили уязвимости, всё равно работает. Любопытное наблюдение делают эксперты: 90% известных уязвимостей в списке CVE находятся в проприетарном ПО, при этом 97% ПО в принципе — использует open source. 

Именно поэтому некорректно говорить, что принцип «тысячи глаз» наивен, на основе больших уязвимостей, которые затронули большое количество пользователей (тот же Log4shell). Уязвимость может быть незаметной, воспроизводимой только в определенных условиях. Реакция мейнтейнеров Log4shell, которые исправили проблему оперативно, была показательной. Именно корпоративные пользователи далеко не сразу отреагировали на исправление, так как именно у них реакция на любое событие проходит через большое количество согласований, а принятие решений по уязвимостям, их исправление и выкатка фиксов могут занимать месяцы. 

Цепочка доверия open source 

Мир open source, как его ни крути, строится на доверии: нельзя сделать абсолютные процессы, нельзя проанализировать все коммиты, нужно доверять друг другу. Именно поэтому разработчики не делают прыжка веры, когда берут проект open source к себе. Они знают, что эти проекты написаны такими же разработчиками. 

Обратная и вместе с тем очень неоднозначная сторона состоит в том, что во многом это взращено на основе доверия к крупным проектам, таким как дистрибутивы Linux. В таких проектах к безопасности относятся с большим вниманием. За счет структуры мейнтейнеров (как минимум апстрима исходного кода и distribution-кода) внутри происходит большое количество процессов, которые формируют software supply chain со всеми текущими требованиями к безопасности, проверкам и автоматизации. Лучшие практики уже на месте: например, Debian использует подпись PGP. Только при наличии кворума подписавшихся мейнтейнеров процесс идет дальше. И каждый пользователь Debian, как только что-то публикуется, может проверить подпись и подлинность пакетов. Получается цепочка доверия: пользователь доверяет подписи, за которой стоит несколько авторитетных людей, которым доверяет индустрия. 

Тем не менее попытка обойтись без четко регламентированных процессов и надежда на то, что «жизнь разберется» (а принцип «тысячи глаз» я не могу назвать никак иначе), привели к разочарованию и выгоранию огромного количества людей, как мейнтейнеров, так и пользователей open source. Так что же пошло не так в цепочке доверия? 

Аспект разработки 

Кейс с Debian и некоторыми другими авторитетными проектами показывает, что при должном внимании к процессам можно выстроить безопасную цепочку разработки и дистрибуции. Но сегодня большинство пакетов распространяется вне подобных процессов. У каждой экосистемы разработчиков есть свой пакетный менеджер: npm (JavaScript), pip (Python), Ruby Gems (Ruby), composer (PHP) и так далее. По принципам работы они похожи на пакетные менеджеры внутри дистрибутивов (как, например, Debian), за исключением того самого консенсуса авторитетных экспертов, которые доверяют пакету, а мы доверяем им.  

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

Получается, что непонятно, как можно доверять чему-то, что было разработано кем-то. А если разработано известным человеком, то случаи, аналогичные xz, показывают: и тут механизм сбоит.  

Некоторые приложения, например на Node.js, тянут за собой при сборке большое количество зависимостей, самостоятельно просканировать которые простому разработчику будет крайне сложно. Один из подходов, который разберем позже, — это генерировать список зависимостей и их уязвимостей, Software Bill Of Materials (SBOM), но с ним также всё неоднозначно. Если зависимостей несколько тысяч, а проект проходит несколько сборок в течение дня, как часто и как глубоко нужно проводить анализ уязвимостей внутри зависимостей? Кто должен решать, критична ли уязвимость, и насколько мы в итоге затормозим развитие проекта? 

Аспект развертывания и управления 

В 2013 году случилась революция в разработке: вышел Docker. Светлые умы индустрии ответили на возрастающую необходимость в автоматизации, развертывании и управлении программным обеспечением. Нагрузка росла стремительно, железо не успевало дешеветь, и нужно было не просто разворачивать что-то куда-то в контейнерах, но и делать это максимально «тесно» в пределах вычислительного ресурса, повышая эффективность утилизации и снижая затраты. 

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

Что это значит с точки зрения безопасности? 

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

Разработчик берет npm-пакет, упаковывает в образ Docker, публикует — и всё: дальше долгое время была полная свобода действий. Позже Docker осознает проблему и попробует решить ее с помощью фичи Verified Build, встроенной в Docker Hub. Фича полезная и правильная: мейнтейнер пишет определение, сборку производит Docker, и пользователь видит в образе код от настоящего мейнтейнера. Частично это решает проблему с доверием, но вряд ли с наличием консенсуса между несколькими экспертами, ведь настоящий мейнтейнер может внести ломающие всё изменения по какой-то своей причине. Тем не менее это большой шаг и инструмент, которым надо пользоваться обязательно. 

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

Люди не очень хотят тратить время на отслеживание происходящего с сотнями контейнеров. Ответил на этот вопрос Google, выпустив Kubernetes, который позволил людям стать дальше от контейнеров. Это оказалось и благом, и проблемой, так как построило еще один слой. В Kubernetes был и есть собственный менеджер пакетов — разумеется, Helm. Он пакует несколько образов Docker и конфигурацию, как пакет с пакетами. 

Промежуточный вывод 

Наслаивание платформенных сервисов — Kubernetes, Docker и других — создало большую проблему для специалистов по безопасности. Установка чарта Helm большого проекта несет за собой потенциальные уязвимости. Сам код проекта верифицирован мейнтейнерами, но верифицированы ли все его зависимости — вопрос, ответ на который с высокой степенью вероятности «нет». 

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

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

Комментарии0
Тоже интересно
Комментировать
Поделиться
Скопировать ссылку
Telegram
WhatsApp
Vkontakte
Одноклассники