
Автоматизированный монитор безопасности цепочки поставок, который опрашивает реестры PyPI и npm, сравнивает новые релизы с предыдущими и использует анализ LLM для обнаружения вредоносных изменений кода с уведомлениями в Slack.
Автоматизированный мониторинг популярных пакетов PyPI и npm на предмет компрометации цепочки поставок. Опрашивает оба реестра на наличие новых релизов, сравнивает каждый новый релиз с предыдущим и использует LLM (через Cursor Agent CLI) для классификации изменений как безвредные или вредоносные. Вредоносные находки вызывают оповещение в Slack.
По умолчанию мониторинг ведется для обеих экосистем. Используйте --no-pypi или --no-npm, чтобы отключить одну из них.
В каждой экосистеме работает свой поток опроса, но они используют общий конвейер анализа и оповещения.
┌─── PyPI ──────────────────────┐ ┌─── npm ───────────────────────┐
│ │ │ │
│ changelog_since_serial() │ │ CouchDB _changes feed │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ ┌────────────┐ │ │ ┌────────────┐ │
│ │ Все PyPI │─┐ │ │ │ Все npm │─┐ │
│ │ события │ │ │ │ │ изменения │ │ │
│ └────────────┘ ▼ │ │ └────────────┘ ▼ │
│ hugovk ──► Список наблюдения │ │ download-counts ─► Список наблюдения│
│ │ │ │ │ │
│ только события "new release" │ │ новые версии с последней эпохи│
└───────────────┬───────────────┘ └───────────────┬───────────────┘
│ │
▼ ▼
┌───────────────────┐ ┌───────────────────┐
│ Загрузить старую +│ │ Загрузить старый +│
│ новую (sdist + │ │ новый (tarball) │
│ wheel) │ │ │
└───────────────────┘ └───────────────────┘
│ │
└─────────────────┬─────────────────┘
▼
┌───────────────┐
│ Unified diff │
│ report (.md) │
└───────┬───────┘
▼
┌───────────────┐ ◄── Анализ LLM
│ Cursor Agent │ (только чтение)
│ CLI (ask mode)│
└───────┬───────┘
│
вердикт?
│
вредоносный │
▼
┌───────────────┐
│ Оповещение в │
│ Slack │
└───────────────┘
Анализ LLM нацелен на поиск:
pip install -r requirements.txt (стандартная библиотека покрывает большую часть инструмента; requests используется для загрузки в Slack)agent, а не IDEWindows (PowerShell):
irm 'https://cursor.com/install?win32=true' | iex
macOS / Linux:
curl https://cursor.com/install -fsS | bash
Проверьте с помощью:
agent --version
Вы должны быть аутентифицированы в Cursor (agent login или установите CURSOR_API_KEY).
Поместите ваш токен бота Slack в etc/slack.json:
{
"url": "https://hooks.slack.com/services/...",
"bot_token": "xoxb-...",
"channel": "C01XXXXXXXX"
}
Боту требуется область chat:write для целевого канала. Поле channel — это ID канала Slack, куда публикуются оповещения.
# Однократный запуск: проанализировать релизы за последние ~10 минут
python monitor.py --once
# Непрерывный мониторинг: отслеживать топ-1000 пакетов (обе экосистемы), опрос каждые 5 мин
python monitor.py --top 1000 --interval 300
# Продакшн: мониторинг топ-15000, оповещение в Slack
python monitor.py --top 15000 --interval 300 --slack
# Только npm, топ-5000
python monitor.py --no-pypi --npm-top 5000
# Только PyPI
python monitor.py --no-npm
| Файл | Назначение |
|---|---|
monitor.py | Основной оркестратор — опрос PyPI + npm, сравнение, анализ, оповещение (параллельные потоки) |
pypi_monitor.py | Автономный опросчик журнала изменений PyPI (используется для исследования) |
package_diff.py | Загрузка и сравнение двух версий любого пакета PyPI или npm |
analyze_diff.py | Отправка различий в Cursor Agent CLI, разбор вердикта |
top_pypi_packages.py | Получение и вывод списка топ-N пакетов PyPI по количеству загрузок |
slack.py | Клиент API Slack (SendMessage, PostFile) |
etc/slack.json | Учетные данные бота Slack |
last_serial.yaml | Сохраненное состояние опроса (серийный номер PyPI + последовательность/эпоха npm) |
logs/ | Ежедневные файлы журнала (monitor_YYYYMMDD.log) |
python monitor.py [ОПЦИИ]
Опции:
--top N Количество отслеживаемых пакетов в каждой экосистеме (по умолчанию: 15000)
--interval SECS Интервал опроса в секундах (по умолчанию: 300)
--once Однократный проход по последним событиям, затем выход
--slack Включить оповещения Slack для вредоносных находок
--model MODEL Переопределить модель LLM (по умолчанию: composer-2-fast)
--debug Включить отладку (включает необработанный вывод агента)
Опции PyPI:
--no-pypi Отключить мониторинг PyPI
--serial N Серийный номер журнала изменений PyPI, с которого начинать
Опции npm:
--no-npm Отключить мониторинг npm
--npm-top N Количество отслеживаемых пакетов npm (по умолчанию: совпадает с --top)
--npm-seq N Последовательность репликации npm, с которой начинать
PyPI и npm работают каждый в своем потоке опроса. Состояние опроса (серийный номер PyPI, последовательность + эпоха npm) сохраняется в last_serial.yaml, чтобы монитор возобновлял работу с места остановки после перезапуска.
Конвейер PyPI:
--interval секунд вызывает changelog_since_serial() — один вызов API, который возвращает все события с момента последней проверки"new release", соответствующие списку наблюдения