|
Professor Seleznov
|
Где-то прямо сейчас один программист не спит и патчит баг в библиотеке, от которой зависит половина интернета. Он делает это бесплатно. Его никто не знает. Если он уйдёт — никто не придёт. В апреле 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). Список не претендует на полноту.-Источник
|