Как обнаружить вредоносный скрипт в setup.cfg вашего Python-проекта

Вы подозреваете, что в файле setup.cfg появился чужой код, или просто хотите убедиться, что проект чист. Файл конфигурации сборки — не самое очевидное место для атаки, но именно поэтому его используют: он запускается при установке пакета, и никто особо не смотрит внутрь. Разберёмся, как найти вредоносный скрипт, не переустанавливая весь проект с нуля.

Почему именно setup.cfg становится мишенью

В типичном Python-проекте setup.cfg управляет метаданными пакета, зависимостями и параметрами сборки. Он читается инструментами вроде setuptools, pytest, mypy и десятками других. Проблема в том, что некоторые из этих инструментов позволяют выполнять произвольные команды при чтении конфигурации. Злоумышленник, получивший доступ к репозиторию или к пакету в прокси-зеркале, может вставить секцию, которая при установке пакета запустит код на машине жертвы.

Реальные векторы атак через setup.cfg:

  • Инъекция в секцию [options] с подменой скриптов установки
  • Внедрение в секции плагинов ([tool:pytest], [mypy] и т.п.) с выполнением кода при запуске утилит
  • Подмена путей к entry points, чтобы при установке пакета регистрировался вредоносный консольный скрипт
  • Использование директив setup_requires для загрузки и выполнения кода до начала установки

Где искать подозрительное: анатомия файла

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

[metadata]
name = my-project
version = 1.2.3
description = A useful library
author = Developer Name

[options]
packages = find:
python_requires = >=3.8
install_requires =
    requests>=2.28
    click>=8.0

[options.entry_points]
console_scripts =
    mytool = mypackage.cli:main

Теперь разберём, какие именно места файла чаще всего модифицируют и на что смотреть.

Секция [options] и параметры установки

Обратите внимание на параметры, которые могут запускать код:

  • setup_requires — список пакетов, которые pip попытается установить перед чтением остальной конфигурации. Если здесь появился незнакомый пакет — это красный флаг.
  • install_requires — зависимости при установке. Подозрительны пакеты с опечатками в названиях популярных библиотек (например, reqeusts вместо requests).
  • scripts — пути к исполняемым скриптам. Если указан файл, которого нет в репозитории, или путь ведёт в неожиданное место — проверьте.

Секция [options.entry_points]

Entry points — это то, что превращает Python-пакет в консольную команду. Злоумышленник может добавить новую точку входа, которая запускает вредоносный скрипт при установке пакета:

[options.entry_points]
console_scripts =
    mytool = mypackage.cli:main
    hidden_backdoor = malicious_pkg.runner:execute

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

Секции сторонних инструментов

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

  • [tool:pytest] — выполнение при запуске тестов
  • [mypy] — запуск при проверке типов
  • [flake8], [pylint] — при статическом анализе
  • [isort], [black] — при форматировании

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

Пошаговый алгоритм проверки

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

  1. Сравните с эталоном. Если проект открытый — скачайте официальный setup.cfg из репозитория и выполните diff. Если закрытый — сравните с последней известной версией из системы контроля версий.
  2. Проверьте все entry points. Откройте секцию [options.entry_points] и для каждой точки входа убедитесь, что модуль существует в проекте и содержит ожидаемую функцию.
  3. Просмотрите зависимости. Пройдитесь по списку install_requires и setup_requires. Для каждого пакета проверьте, что он действительно нужен проекту и что название не содержит опечаток.
  4. Ищите скрытые секции. В setup.cfg могут быть секции, которые вы не добавляли. Просмотрите весь файл и проверьте каждую секцию квадратных скобок.
  5. Проверьте наличие исполняемых файлов. Если в setup.cfg указаны скрипты (scripts или entry_points), найдите эти файлы в проекте и проверьте их содержимое.
  6. Запустите в изолированной среде. Установите пакет в чистое виртуальное окружение и посмотрите, какие файлы были созданы, какие команды запущены.

Инструменты для автоматизированного анализа

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

Инструмент Что проверяет Как использовать Уровень сложности
pip-audit Известные уязвимости в зависимостях pip-audit -r requirements.txt Простой
safety Уязвимости в установленных пакетах safety check Простой
bandit Небезопасные конструкции в Python-коде bandit -r ./src Средний
pyroma Корректность метаданных пакета pyroma . Простой
check-python-version Соответствие заявленных и реальных версий Ручная проверка по выводу pip install Простой
diff против эталона Любые изменения в файле diff setup.cfg reference_setup.cfg Простой

Отдельно стоит упомянуть pip install --dry-run (доступен в pip 22.2+). Он показывает, что будет установлено, без реальной установки. Полезно для быстрой проверки зависимостей.

Красные флаги: что должно насторожить

Вот конкретные признаки, при которых стоит остановиться и разобраться глубже:

  • В файле появились секции, которые вы не создавали, особенно с названиями вроде [tool:unknown] или [custom]
  • В install_requires есть пакеты, не упомянутые в документации проекта
  • Entry points ведут к модулям, которых нет в исходном коде
  • В секциях инструментов указаны пути к файлам вне проекта (/tmp/, C:\Users\)
  • Файл содержит строки с вызовами eval(), exec(), os.system(), subprocess — в setup.cfg это не имеет смысла
  • Размер файла неожиданно вырос по сравнению с предыдущей версией
  • В файле есть закомментированные строки с подозрительным кодом — иногда злоумышленники оставляют «спящие» вставки

Частые ошибки при проверке

Даже опытные разработчики допускают одни и те же промахи при аудите setup.cfg:

  • Проверяют только секцию [metadata]. Метаданные относительно безопасны — основная атака идёт через [options] и entry points.
  • Игнорируют секции сторонних инструментов. Если вы не используете mypy, секция [mypy] в файле не должна быть. Любая незнакомая секция — подозрительна.
  • Не проверяют транзитивные зависимости. Вредоносный код может быть не в основном пакете, а в одном из его зависимых пакетов. Проверяйте всю цепочку.
  • Слепо доверяют файлам из форков. Если вы форкнули чужой проект, его setup.cfg мог быть модифицирован до вашего форка.
  • Не изолируют при тестировании. Установка подозрительного пакета в системный Python — плохая идея. Используйте virtualenv или контейнер.

Что делать, если нашли подозрительное

Нашли что-то странное в setup.cfg? Не паникуйте, но действуйте методично:

  1. Не запускайте pip install для этого пакета в текущем окружении.
  2. Сохраните копию файла для анализа — зафиксируйте контрольную сумму.
  3. Проверьте остальные файлы проекта — если модифицировали setup.cfg, могли затронуть и setup.py, pyproject.toml, скрипты в bin/.
  4. Сообщите maintainer проекта или в службу безопасности вашей организации.
  5. Заблокируйте установку пакета в вашей системе сборки, пока не разберётесь.

Сценарии действий в зависимости от ситуации

Если вы — разработчик проекта и нашли подозрительное в своём файле: Откатите изменения через git, проверьте историю коммитов на предмет несанкционированных изменений, обновите зависимости, опубликуйте чистую версию. Если проект публичный — уведомите пользователей о компрометации.

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

Если вы — DevOps/SRE и пакет уже установлен в production: Проверьте логи на предмет необычных действий в момент установки. Запустите проверку целостности файлов. При подтверждении компрометации — откатитесь на чистую версию и заблокируйте установку скомпрометированного пакета.

Как предотвратить проблему в будущем

Лучшее лечение — профилактика. Вот что реально работает:

  • Фиксируйте зависимости с контрольными суммами. Используйте pip-compile из pip-tools с хешами или poetry lock — это не даст подменить пакет незаметно.
  • Проверяйте файлы перед коммитом. Настройте pre-commit хук, который проверяет setup.cfg на наличие подозрительных секций.
  • Используйте изолированные окружения для сборки. Docker-контейнер или чистый virtualenv — не дадут вредоносному коду повлиять на систему.
  • Регулярно аудитируйте зависимости. Запускайте pip-audit или safety по расписанию, хотя бы раз в неделю.
  • Ограничьте источники пакетов. Используйте только проверенные индексы и прокси-серверы с подписью пакетов.

Итог

Вредоносный скрипт в setup.cfg — это не теория, а реальный вектор атак, который эксплуатирует доверие к процессу установки пакетов. Чтобы обнаружить проблему:

  • Сравнивайте текущий файл с эталоном
  • Проверяйте все entry points и зависимости
  • Ищите незнакомые секции и подозрительные пути
  • Используйте pip-audit, bandit и diff для автоматизации
  • Никогда не устанавливайте подозрительные пакеты без изоляции

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

Оцените статью
PEFile — Безопасность и технологии простым языком