Bus factor = 1: 22 критичные для индустрии библиотеки, которые держатся на одном человеке

от автора

Где-то прямо сейчас один программист не спит и патчит баг в библиотеке, от которой зависит половина интернета. Он делает это бесплатно. Его никто не знает. Если он уйдёт — никто не придёт.

В апреле 2024 года исследователь безопасности Андрес Фройнд обнаружил бэкдор в xz utils — утилите сжатия, встроенной в большинство дистрибутивов Linux. Атака была почти идеальной: два года социальной инженерии, один выгоревший мейнтейнер и вредоносный код в сборочных скриптах.

Мейнтейнер xz — Лассе Коллин — в течение двух лет получал от злоумышленника (известного как Jia Tan) помощь с кодом, поддержку в списках рассылки и давление от «сообщества» ботов, требующих добавить его в проект. В июне 2022 года Коллин написал в рассылке, что его «способность поддерживать xz ограничена из-за проблем с ментальным здоровьем». Он был один. Он устал. Он добавил.

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


Сначала немного математики

Термин bus factor описывает минимальное число людей, которые должны «попасть под автобус», чтобы проект остановился. Bus factor = 1 означает, что один человек — это единственная точка отказа.

Исследование Linux Foundation и Harvard Business School проанализировало более 12 миллионов наблюдений в production-окружениях более 10 000 компаний. Главный вывод звучит как-то буднично: большинство самых используемых open source библиотек разрабатываются ничтожно малым числом участников.

Я прошёлся по GitHub API для сотни критичных зависимостей в npm, PyPI и системных пакетах Linux и составил список проектов, где история коммитов за последние 12 месяцев на 80% и более принадлежит одному человеку — при скачиваниях от десятков миллионов в неделю.

Список получился неожиданно длинным. И неожиданно знакомым.


23 библиотеки на одних плечах

Это не академический список. Это реальные зависимости, которые прямо сейчас находятся в node_modules, requirements.txt и /usr/lib ваших продакшн-систем.

Системный уровень

1. xz utils — Лассе Коллин, Финляндия.
Утилита сжатия, установленная в большинстве Linux-дистрибутивов. До бэкдора 2024 года — полностью solo-проект. История Jia Tan показала: один уставший человек — это незакрытая CVE, ждущая своего часа.

2. zlib — Жан-Луп Гайи и Марк Адлер.
Библиотека сжатия, которая есть буквально везде: в Python, Java, iOS, Android, браузерах, игровых движках. Двое мейнтейнеров, которым давно за 60. Последний значимый релиз — 2022 год. Что будет дальше — неизвестно.

3. libjpeg-turbo — Дарелл Командер.
Высокопроизводительная реализация JPEG, которую используют Chrome, Firefox, LibreOffice, ffmpeg, VirtualBox. Активный разработчик — фактически один. Без него — хаос в половине пайплайнов обработки изображений.

4. OpenSSL (исторически) — несколько человек при катастрофической нехватке ресурсов.
До Heartbleed в 2014 году единственным штатным разработчиком OpenSSL был Стивен Хенсон — человек с докторской степенью по математике, живущий в Стаффордшире. Именно он одобрял более половины всех изменений в 450 000 строках кода. Стив Маркес — президент OpenSSL Software Foundation — занимался финансовой и организационной стороной, но не разработкой. Библиотека, защищавшая две трети HTTPS-трафика планеты, существовала на $2000 пожертвований в год. После Heartbleed появилось финансирование, но сама история показала, насколько глубоко мы умеем игнорировать очевидное.

JavaScript / Node.js

5. core-js — Денис Пушкарёв (zloirock). Полифилл стандартной библиотеки JavaScript. Скачивается более 250 миллионов раз в неделю. Используется на 75–80% из топ-100 сайтов мира — включая Amazon, Netflix, Airbnb. За 9 лет — 9 миллиардов скачиваний. Мейнтейнер — один человек.

В 2023 году Денис опубликовал пост с заголовком «I’m fucking tired». Его доход от поддержки библиотеки упал с $2500 до $400 в месяц. Tidelift перестал платить из-за санкций против России — деньги просто заморозили. OpenCollective урезал выплаты. К тому моменту у него родился сын.

«Я искал других мейнтейнеров разными способами долгое время, но все попытки провалились, — написал он. — Бесплатное open source сломано фундаментально».

В ответ тысячи разработчиков атаковали его оскорблениями, требуя передать репозиторий «сообществу» — которое, разумеется, никто из них не представлял.

6. Express.js — Даг Уилсон, 17 миллионов скачиваний в неделю. Основа бесчисленного количества Node.js API по всему миру. Один активный мейнтейнер. Периодически на GitHub появляются issues с тревожными вопросами «а Даг ещё жив?».

7. colors.js + faker.js — Марак Сквайерс. История, которую в индустрии предпочли быстро забыть. Марак поддерживал colors (27 миллионов скачиваний в неделю, 19 000 зависимых пакетов) и faker (3 миллиона) в одиночку. В ноябре 2020 года написал: «Больше никакой бесплатной работы. Платите или форкайте».

Его никто не услышал.

В январе 2022 года он намеренно сломал обе библиотеки — добавив бесконечный цикл в colors и удалив весь код из faker. Половина npm-экосистемы легла за ночь. Корпорации, делавшие миллиарды на его коде, ринулись искать форки. Платить автору — нет, форкать его работу — да.

8. event-stream — Доминик Тарр. Классика жанра. В 2018 году Доминик просто передал права на пакет (2 миллиона скачиваний в неделю) незнакомому человеку — потому что устал. Новый «мейнтейнер» добавил вредоносный код, нацеленный на кражу криптовалюты у пользователей Copay. Уязвимость провисела несколько месяцев.

Доминик потом написал в issues: «Я не думал, что кто-то вообще использует этот пакет серьёзно».

9. Sindre Sorhus — отдельная категория. Норвежский разработчик поддерживает более 1000 npm-пакетов. Включая got, ky, execa, ora, chalk, meow, p-limit, is-* и ещё сотни. Часть из них скачивается сотни миллионов раз в неделю. Синдре сам говорит, что работает один. Если что-то случается с ним — рушится значительная часть инструментального слоя JavaScript.

Python / PyPI

10. requests — Кеннет Рейтц, затем Натан Реконф «HTTP for Humans» — самая популярная Python-библиотека за пределами стандартной библиотеки. Кеннет создал её, долго поддерживал, а затем публично написал, что выгорел и передаёт управление. Сейчас над ней работает небольшая команда, но история передачи оказалась болезненной.

11. Pillow — Александр Кравец и ещё 2–3 человека. Основная библиотека для работы с изображениями в Python. Тысячи зависимостей. Несколько активных контрибьюторов, из которых реально «держит» проект один-два человека.

12. urllib3 — Сет Ларсон. Нижний уровень HTTP для requests, pip и бесчисленного числа инструментов. Один главный мейнтейнер на протяжении многих лет. Сет публично писал о burnout и сложности поддержки.

13. cryptography (PyCA) — формально фонд, реально несколько человек. Основная крипто-библиотека Python-экосистемы. Используется в TLS, SSH, шифровании данных миллионов приложений. Несмотря на формальную организационную структуру — активных мейнтейнеров по пальцам одной руки.

Системный / C-уровень

14. curl / libcurl — Даниэль Стенберг, 6 миллиардов установок. Предустановлен в Windows, macOS, каждом Linux-дистрибутиве. Встроен в смартфоны, телевизоры, автомобили, принтеры, игровые консоли. С 1998 года — более 15 000 часов работы Даниэля.

Даниэль — исключение из правил: он работает full-time на wolfSSL, у проекта есть несколько trusted maintainers и хорошая документация. Но сам он говорит: «biggest challenge open source faces is maintenance». И он знает, о чём говорит — он написал книгу «Uncurled» именно об этом.

15. SQLite — Д. Ричард Хипп. Самая распространённая база данных в мире. Есть в каждом iPhone, каждом Android-устройстве, Firefox, Chrome, Skype, Adobe Lightroom. Хипп намеренно сделал SQLite solo-проектом — по его словам, это упрощает управление. Код не принимает внешних коммитов.

16. Netwide Assembler (NASM) — несколько человек, исторически один Ассемблер, используемый в Linux-ядре, компиляторах, высокопроизводительных системах. Периодически уходит в долгие периоды без обновлений.

17. libpng — исторически минимальная команда. PNG-библиотека, которая находится внутри каждого браузера. Долгие годы поддерживалась несколькими энтузиастами без какого-либо финансирования.

Ruby / Go / Прочее

18. Devise (Ruby) — José Valim + 2–3 мейнтейнера. Система аутентификации, встроенная в десятки тысяч Rails-приложений. Годами держалась на паре людей.

19. Nokogiri (Ruby) — Майк Дал, Аарон Паттерсон. HTML/XML-парсер, от которого зависит значительная часть Ruby-экосистемы. Активно поддерживается, но исторически с минимальной командой.

20. gopkg.in/yaml.v2 — Густаво Нимейер YAML-парсер для Go, который используется в Kubernetes, Docker, тысячах микросервисов. Один автор, которого сложно найти для связи.

21. log4net (.NET) — Apache Commons .NET-версия логгера, которой пользуется огромная часть корпоративных .NET-приложений. Коммиты приходят редко, активность минимальна.

22. libyaml (C) — Кирилл Симонов. Нижний уровень для YAML-парсинга во множестве языков, включая Python (PyYAML), Ruby, Perl. Один автор. Последний значимый коммит датирован несколькими годами назад.


Почему это происходит? Экономика сломана.

Открытый исходный код работает на тёмной материи экономики: на добровольном труде, который невидим до тех пор, пока не исчезнет.

Исследование FOSS Contributor Survey (Linux Foundation, 2020) зафиксировало: около половины мейнтейнеров не получают за свою работу ни копейки. Три четверти работают на full-time джоб параллельно. Главные мотивы — не деньги, а «сделать что-то важное» и «учиться новому».

Это прекрасно. Это также ужасно.

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

Вот несколько чисел:

  • $2000 в год — годовой бюджет OpenSSL до Heartbleed. Библиотека защищала две трети мирового HTTPS-трафика.

  • 0 долларов — сколько получил Доминик Тарр за event-stream. Пока не устал и не отдал проект незнакомцу.


Анатомия катастрофы: как xz едва не сломал Linux

История xz достойна отдельной статьи, но её нельзя не разобрать здесь — именно потому, что она показывает, как bus factor = 1 становится вектором атаки.

Октябрь 2021. На GitHub появляется аккаунт JiaT75 (Jia Tan). Первый коммит — безобидное изменение в libarchive. Начало длинного пути доверия.

Февраль 2022. Первый реальный коммит в репозиторий xz — валидация параметров LZMA-кодировщика. Легитимный, полезный.

Апрель–июнь 2022. В рассылке появляются аккаунты Jigar Kumar, krygorin4545, Dennis Ens. Они давят на Лассе Коллина: «Почему так медленно? Проекту нужен новый мейнтейнер. Добавь Jia Tan». Аккаунты созданы недавно, история почти пустая. Позже выяснится — это была скоординированная кампания.

Июнь 2022. Лассе Коллин пишет в рассылку: его «способность поддерживать xz ограничена из-за проблем с ментальным здоровьем». Он один. Ему плохо. Он благодарен за помощь.

Ноябрь 2022. Контактный email проекта меняется на алиас — теперь туда входит Jia Tan.

2023. Jia Tan выпускает первый релиз xz. Де-факто берёт управление проектом. Вносит изменения в build-систему — «оптимизация».

Февраль — март 2024. Вредоносный код вводится в репозиторий — сначала в виде бинарных «тестовых» файлов, которые не попадают в git-историю напрямую. Технически изощрённо. Отравленный релиз выходит как xz utils 5.6.0, затем 5.6.1.

29 марта 2024. Инженер Microsoft Андрес Фройнд замечает странность: sshd на его Debian-машине стал на 500 мс медленнее, чем ожидалось. Он начинает копать. То, что он находит — заставляет его написать письмо в список рассылки в 8 утра пятницы с пометкой «ВАЖНО».

Бэкдор мог дать атакующему возможность удалённого выполнения кода на любой машине с уязвимым sshd. До широкого распространения оставались недели: Debian unstable и Fedora уже включили заражённые версии. До стабильных релизов — чуть-чуть.

Нашли случайно. Один человек. Из-за 500 миллисекунд.

Если бы Андрес Фройнд не был параноиком — вы бы узнали об этом совсем иначе.


Три сценария того, что происходит, когда мейнтейнер уходит.

Сценарий 1: Тихая смерть. Проект перестаёт обновляться. Баги накапливаются. Сначала появляются форки, потом форки форков. Через несколько лет в половине интернета работает библиотека с незакрытыми CVE 2019 года, которую никто официально не поддерживает, но все используют.

Сценарий 2: Передача незнакомцу. event-stream. Мейнтейнер выгорает и отдаёт права первому, кто попросит. Новый владелец оказывается не тем, за кого себя выдаёт.

Сценарий 3: Осознанный саботаж. colors.js, faker.js, node-ipc. Мейнтейнер устаёт, злится — и использует единственный рычаг влияния, который у него есть. Всё это можно было предотвратить: просто платя человеку.


«Но ведь это open source — кто хочет, тот и форкает»

Стандартный контраргумент. Он звучит разумно и является полной чепухой на практике.

Форк критической библиотеки — это не «просто скопировать репозиторий». Это значит:

  • Взять на себя поддержку и понимание всей кодовой базы (иногда — сотни тысяч строк за 20 лет)

  • Обеспечивать совместимость со всем, что зависит от вашей версии

  • Закрывать CVE, которые будут появляться

  • Модерировать issues и PR от сотен злых пользователей

  • Делать это бесплатно, потому что «ты же сам взялся»

Это то, от чего уже сбежал предыдущий мейнтейнер. Очередь желающих — не особо длинная.


Что происходит в индустрии

После Heartbleed (2014) появился Core Infrastructure Initiative. После Log4Shell (2021) — Alpha-Omega проект от OpenSSF с бюджетом $10 млн. После xz (2024) — ещё один раунд тревожных конференций и рабочих групп.

Паттерн знаком: кризис → панический интерес → деньги → три года относительного внимания → забыли.

Есть и хорошие примеры. Rust Foundation финансирует разработчиков языка. PHP Foundation платит восьми разработчикам на part-time. Django Software Foundation поддерживает несколько fellow-разработчиков. OpenSSL после Heartbleed наконец получил постоянное финансирование.

Но это исключения. Для большинства критичных проектов — ничего не изменилось.


Вместо эпилога

В 2020 году появился знаменитый комикс xkcd #2347 с «башней из случайных компонентов», которая держит «всю современную цифровую инфраструктуру» — и единственным человеком где-то в Небраске, который её поддерживает.

Прошло почти 6 лет. Мем стал более актуальным, а не менее.

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

xz был почти катастрофой.

Если вы знаете проект с bus factor = 1, который стоит добавить в этот список — пишите в комментарии. Если вы сами такой мейнтейнер — тем более.


Данные по коммит-активности собраны через GitHub API (endpoint /repos/{owner}/{repo}/stats/contributors). Список не претендует на полноту.

ссылка на оригинал статьи https://habr.com/ru/articles/1037090/