В последнее время участились инциденты с вирусами в публичных репозиториях. В этой статье рассмотрим два популярных метода внедрения вредоносного ПО в пакеты PyPI, и как с ними бороться с помощью файла блокировки MLOps-разработчику.
Вредоносное ПО проникло в цепь поставок
Цепь поставок в производстве подразумевает все этапы от создания продукта до поставки его клиенту. В мире ПО цепь поставок — это всё, что воздействует на продукт до того, как он будет внедрен в информационные системы. Это всё включает написанный код, зависимости, среды сборки, среды разработки, каждый компонент, который взаимодействует с продуктом.
Появление термин “цепь поставки” в последнее время связывается с кибератаками. Крупный инцидент произошел с Solarwinds Orion: система сборки и все новые релизы с марта по июнь 2020 года были заражены вредоносным ПО [1]. В результате клиенты, получившие обновления, были скомпрометированы. Несмотря на то, что этот инцидент был хорошо освещен в СМИ, всё больше кибератак заканчиваются успехом (а многие связаны с обычной халатностью разработчиков, а не с мощными схемами взлома). Cloud Native Computing Foundation отслеживает атаки и выкладывает их в своем репозитории на Github [2].
Как управлять зависимостями в Python
Как правило, за нас написали уже многие программы. Некоторыми из них можно воспользоваться в своих личных целях, такие программы оформляются в виде пакетов (библиотек) и выкладываются в публичные репозитории. Для Python-разработчиков существует PyPI (Python Package Index). И с этого момента здесь нужно быть осторожным.
При работе с публичными репозиториями есть два вида способа взлома:
- создание пакета с похожим названием
- перенаправление на свой ресурс для загрузки.
Первый способ направлен на каждого Python- или MLOps-разработчика, который приучен загружать пакеты следующим образом:
pip install <my package>
Злоумышленник публикует пакеты с похожим названием, надеясь на то, что разработчик допустит ошибку в названии запрашиваемого пакета. Например, пакет dateutil имел своего злого двойника в виде python3-dateutil [3].
Разработка и внедрение ML-решений
Код курса
MLOPS
Ближайшая дата курса
10 марта, 2025
Продолжительность
24 ак.часов
Стоимость обучения
54 000 руб.
Второй метод полагается на то, как работает пакетный менеджер pip. Команда, которая может привести к неблагоприятным последствиям:
pip install <my package> --extra-index-url <url internal index>
Как только набрав эту команду происходит следующее:
- Проверяется пакет существует ли в указанном URL.
- Проверяется пакет существует ли в PyPI.
- Устанавливается пакет. Если пакет есть и там и там, то установить нужно с того ресурса, где версия пакета наивысшая.
Третий пункт и определяет логику поведения злоумышленника: нужно в репозитории указать версию с большим числом, — далее будет скачан именно этот пакет. Причем название пакета может быть правильным, но на одном из источников содержится нежеланная программа. Поэтому данная команда небезопасная сама по себе.
Как MLOps-разработчику защититься от вредоносного ПО?
Защититься от неправильного правописания вам поможет файл блокировки (lock file). Такой файл должен иметь следующие свойства:
- Указанные версии, т.к. нас должны интересовать определенные версии пакета;
- Хэши необходимы для проверки целостности пакета;
- Дерево зависимостей нужны для контроля над зависимостями наших зависимостей;
Отсюда можно сделать вывод, что requirements.txt
, создаваемый через команду pip freeze
, которым так часто пользуется Python-разработчики, нельзя считать хорошим примером файла блокировки, поскольку кроме указанных версий в нём ничего нет.
Рекомендуемыми инструментами, дополняющим pip, будут являться pipenv и pip-tools. Для первого достаточно установить пакет через pipenv install
, затем создать файл блокировки через pip lock
. В pip-tools хэш генерируются через pip-compile:
$ pip install pip-tools==6.3.0 $ echo "sacremoses==0.0.46" >> requirements.in $ pip-compile --generate-hashes
Теперь как только у вас есть захэшированные пакеты с указанными версиями и деревом зависимостей вы можете установить все необходимые пакеты, указанные в requirements.txt
:
pip install --require-hashes -r requirements.txt
Так, вы точно удостоверитесь, что будут установлены желаемые пакеты. Как минимум, мы избежали первого метода злоумышленников. Что насчет со загрузки с других ресурсов? Если вы взгляните на документацию pip, то увидите несколько опций по загрузке с внешних источников: --extra-index-url
и --index-url
. разница между ними в том, что --index-url
загрузит пакет только из репозитория по указанной ссылке. Поэтому используйте лучше эту опцию. И последнее, не обновляйте пакеты сразу, иначе автор пакета может сам умышленно сломать вам всё, как это произошло недавно с одним пакетом npm (это JavaScript) [4].
Ещё больше о безопасности проектов вы узнаете на специализированном курсе по MLOPS «Разработка и внедрение ML-решений» в лицензированном учебном центре обучения и повышения квалификации разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве.
- https://www.businessinsider.com/solarwinds-hack-explained-government-agencies-cyber-security-2020-12?op=1
- https://github.com/cncf/tag-security/tree/main/supply-chain-security/compromises
- https://snyk.io/blog/malicious-packages-found-to-be-typo-squatting-in-pypi/
- https://www.opennet.ru/opennews/art.shtml?num=56479