В последнее время участились инциденты с вирусами в публичных репозиториях. В этой статье рассмотрим два популярных метода внедрения вредоносного ПО в пакеты 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
Ближайшая дата курса
7 октября, 2024
Продолжительность
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