Перейти к содержимому

Protestware: как защитить проект от идеологических атак через зависимости

Protestware: как идеологически мотивированные атаки проникают в код и как защитить проект

В цепочке поставок программного обеспечения опасность представляют не только классические уязвимости и вредоносные пакеты, созданные ради кражи денег или данных. Отдельную категорию составляют компоненты, авторы которых намеренно добавляют разрушительную, ограничивающую или политизированную функциональность. Такое явление называют protestware.

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

С точки зрения информационной безопасности мотивация не меняет сути угрозы. Если зависимость способна остановить приложение, уничтожить файлы или нарушить бизнес-процессы, она становится полноценным риском для программной цепочки поставок - независимо от того, руководствовался автор финансовой выгодой или личными убеждениями.

Чем protestware опасен для проекта

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

Настоящая опасность начинается тогда, когда идеологическое послание сопровождается воздействием на систему. Код может:

- блокировать запуск приложения;
- повреждать, удалять или перезаписывать файлы;
- нарушать работу серверов и командных инструментов;
- останавливать важные бизнес-процессы;
- ограничивать доступ пользователей из определенных регионов;
- отправлять данные на внешние сервисы;
- распространять сообщения без согласия владельца продукта.

Protestware особенно трудно обнаружить по нескольким причинам. Он часто находится в популярном пакете, которому доверяют разработчики и системы сборки. Антивирус или сканер может не считать такой код подозрительным, если он размещен в официальном репозитории и подписан известным мейнтейнером.

Кроме того, вредоносная логика нередко активируется не сразу. Она может ждать определенной даты, времени, локали, IP-адреса, переменной окружения или конкретного действия пользователя. Такие механизмы называют логическими и временными "бомбами".

Как протестный код попадает в инфраструктуру

Наиболее распространенный путь - зависимость проекта от внешнего open source-пакета. Компонент может быть добавлен напрямую разработчиком или прийти транзитивно, то есть через другую библиотеку.

Особенно опасны сценарии, в которых код запускается автоматически:

- во время `install` или `postinstall`;
- при импорте модуля через `require` или `import`;
- при сборке контейнера;
- во время генерации клиентского или серверного бандла;
- при запуске CLI-инструмента;
- через скрипты CI/CD.

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

Показательные случаи

node-ipc и peacenotwar

Библиотека `node-ipc` добавляла в состав зависимостей модуль `peacenotwar`. При установке тот определял внешний IP-адрес машины через сервисы геолокации и устанавливал регион пользователя.

Если система находилась в России или Беларуси, код изменял файлы на диске: оригинальное содержимое заменялось изображениями или символами в виде сердец. Дополнительно на рабочем столе создавался файл `WITH-LOVE-FROM-AMERICA.txt`.

Для выполнения действий применялись обфусцированный код, `execSync`, а также системные команды вроде `cp` и `echo`. Вредоносная логика была спрятана в установочных хуках и в динамическом подключении `peacenotwar`.

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

colors.js

Пакет `colors` широко использовался для цветного вывода в терминале. В одну из версий был добавлен бесконечный цикл, который выводил в консоль не-ASCII-символы. Он запускался уже при подключении библиотеки через `require('colors')`.

Поскольку цикл выполнялся в основном потоке Node.js, event loop блокировался. CLI-программы и серверы, импортировавшие пакет во время старта, переставали нормально работать. Это приводило к отказу в обслуживании.

Случай также продемонстрировал другую проблему: критически важная библиотека может фактически зависеть от решений одного мейнтейнера. Если в проекте нет независимого ревью и резервной команды сопровождения, один человек получает возможность существенно повлиять на пользователей.

faker.js

История с `faker.js` показала, что саботаж может выражаться не только в уничтожении данных. В код популярной библиотеки был добавлен крупный текстовый фрагмент, из-за чего пакет перестал выполнять ожидаемую функцию.

Для разработчиков, использовавших его в тестах и генерации данных, это означало внезапные ошибки сборки и нарушение автоматизированных процессов. Поскольку библиотека применялась в большом количестве проектов, локальное изменение быстро распространилось по экосистеме.

es5-ext

В `es5-ext`, низкоуровневом пакете, который применяется в том числе в инструментах сборки вроде webpack, появилась логика, зависящая от времени и региональных настроек.

Код проверял системное время и локаль. При выполнении заданных условий, например ночью - между 22:00 и 06:00, - он мог выводить политические сообщения и влиять на работу программ.

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

Как обнаружить protestware

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

Полезно контролировать:

1. изменения манифестов и lock-файлов;
2. новые зависимости;
3. установочные скрипты;
4. вызовы оболочки и системных команд;
5. сетевые обращения во время установки;
6. работу с IP-адресами, локалью и системным временем;
7. операции записи, удаления и массового изменения файлов;
8. динамический импорт модулей;
9. обфускацию и необычные участки кода;
10. резкое изменение размера или поведения пакета.

Особое внимание следует уделять хукам `preinstall`, `install` и `postinstall`. Они выполняются автоматически и часто обладают широкими правами. Если бизнес-процесс не требует таких скриптов, их стоит отключать на уровне менеджера пакетов или сборочного контура.

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

Что делать после обнаружения угрозы

Если подозрительный компонент уже попал в проект, не следует ограничиваться его удалением из исходного кода. Нужно определить, где он успел выполниться и какие действия совершил.

Рекомендуемый порядок:

- остановить затронутые сборки и публикацию артефактов;
- зафиксировать версии пакетов и журналы выполнения;
- изолировать рабочие станции и среды сборки;
- проверить файловую систему на изменения;
- сравнить артефакты с доверенными контрольными суммами;
- определить момент появления вредоносной версии;
- проверить CI/CD, контейнерные образы и кэш зависимостей;
- отозвать потенциально скомпрометированные токены и ключи;
- заменить пакет на безопасную версию или альтернативу;
- пересобрать продукт с чистого окружения;
- уведомить заинтересованные команды и заказчиков.

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

Как снизить риск

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

Зависимости лучше хранить во внутреннем зеркале или прокси-репозитории. Это позволяет контролировать, какая версия попадает в сборку, не зависеть от внезапных публикаций и быстро заблокировать проблемный компонент.

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

Полезны и технические ограничения: минимальные права процесса, запрет доступа установочных скриптов к продуктивным данным, фильтрация исходящих соединений, запуск сборок в одноразовых контейнерах и регулярное обновление инструментов анализа зависимостей.

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

Protestware нельзя полностью исключить одной антивирусной проверкой. Защита требует сочетания инвентаризации, анализа поведения, изоляции сборок, контроля обновлений и готового плана реагирования. Чем раньше организация видит полный состав своей цепочки поставок, тем меньше вероятность, что незаметное изменение одной зависимости превратится в масштабный сбой продукта.

Прокрутить вверх