Обезопась себя: что нужно знать о репозиториях PyPI

автор рубрика
Обезопась себя: что нужно знать о репозиториях PyPI

В последнее время участились инциденты с вирусами в публичных репозиториях. В этой статье рассмотрим два популярных метода внедрения вредоносного ПО в пакеты PyPI, и как с ними бороться с помощью файла блокировки MLOps-разработчику.

Вредоносное ПО проникло в цепь поставок

Цепь поставок в производстве подразумевает все этапы от создания продукта до поставки его клиенту. В мире ПО цепь поставок — это всё, что воздействует на продукт до того, как он будет внедрен в информационные системы. Это всё включает написанный код, зависимости, среды сборки, среды разработки, каждый компонент, который взаимодействует с продуктом.

Цепь поставок 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 февраля, 2022
Длительность обучения
24 ак.часов
Стоимость обучения
45 000 руб.

Второй метод полагается на то, как работает пакетный менеджер pip. Команда, которая может привести к неблагоприятным последствиям:

pip install <my package> --extra-index-url <url internal index>

Как только набрав эту команду происходит следующее:

  1. Проверяется пакет существует ли в указанном URL.
  2. Проверяется пакет существует ли в PyPI.
  3. Устанавливается пакет. Если пакет есть и там и там, то установить нужно с того ресурса, где версия пакета наивысшая.

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

Как 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 в Москве.

Источники
  1. https://www.businessinsider.com/solarwinds-hack-explained-government-agencies-cyber-security-2020-12?op=1
  2. https://github.com/cncf/tag-security/tree/main/supply-chain-security/compromises
  3. https://snyk.io/blog/malicious-packages-found-to-be-typo-squatting-in-pypi/
  4. https://www.opennet.ru/opennews/art.shtml?num=56479
Комментировать