
Публичный сканер пакетов для сообщества
Молниеносно простой, Docker‑ориентированный сканер цепочки поставок npm. Один файл compose запускает:
Это версия только для контейнеров. Проект можно масштабировать с помощью EC2, SQS и RDS. Большая часть инфраструктуры уже подготовлена в наборе инструментов.
scan.yml (белые списки, пороги, YARA)scan_runs) готова к работе~/.aws)docker-compose.yml – сервисы: db, enumerator, fetcher, analyzer, dashboard, init-dbenumerator/ – Node-воркер, строящий NDJSON-очередьfetcher/ – Node-воркер, загружающий tar-архивы (+ выгрузка в S3, если включено)analyzer/ – Python-анализатор статики (+ опциональный YARA inline)dashboard/ – Streamlit-приложение (порт 8501)infra/migrations.sql – основная схема БД (packages, versions, findings, scores, indexes)infra/20251106_scan_runs.sql – таблица истории сканированийscan.yml – конфигурация анализа (правила, оценка, белые списки, YARA)scripts/run_pipeline.sh – запуск enumerate → fetch → analyzescripts/init_db.sh – инициализация схемы БДscripts/test_setup.sh – автоматическая проверка установкиSCANNING_GUIDE.md – подробные стратегии сканирования и примерыПредварительные требования: Docker Desktop (или движок) с Compose v2.
curl -fsSL https://raw.githubusercontent.com/MHaggis/Package-Inferno/main/install.sh | bash
Клонирует репозиторий в ~/package-inferno и выводит инструкции для начала работы.
Загрузите и запустите предварительно собранные контейнеры из GitHub Container Registry:
# Клонируйте репозиторий (для конфигурационных файлов и скриптов)
git clone https://github.com/MHaggis/Package-Inferno.git
cd Package-Inferno
# Запустите с предварительно собранными образами
docker compose -f docker-compose.ghcr.yml up -d db
./scripts/init_db.sh
SEEDS="lodash,express" docker compose -f docker-compose.ghcr.yml run --rm enumerator
docker compose -f docker-compose.ghcr.yml run --rm fetcher
docker compose -f docker-compose.ghcr.yml run --rm analyzer
Доступные образы:
ghcr.io/mhaggis/package-inferno/enumerator:mainghcr.io/mhaggis/package-inferno/fetcher:mainghcr.io/mhaggis/package-inferno/analyzer:mainЗапустите тестовый скрипт для проверки установки:
./scripts/test_setup.sh
Он выполнит:
docker compose up -d db
./scripts/init_db.sh
./scripts/run_pipeline.sh
docker compose up -d dashboard
# откройте http://localhost:8501
Результаты попадают в ./out/findings/*.findings.json и в таблицу findings при включённой БД.
PackageInferno поддерживает несколько стратегий сканирования в зависимости от ваших целей:
| Режим | Сценарий использования | Скорость | Охват | Команда |
|---|---|---|---|---|
| Конкретные seeds | Тестирование/анализ известных пакетов | Самый быстрый | Целевой | SEEDS="pkg1,pkg2" |
| Небольшая партия | Проверка настройки, пробное сканирование | Быстрый | 10-100 пакетов | MAX_CHUNKS=2 CHUNK_LIMIT=10 |
| Полный реестр | Комплексный аудит цепочки поставок | Часы-дни | 2M+ пакетов | MAX_CHUNKS=0 CHUNK_LIMIT=100 |
| Лента изменений | Мониторинг новых релизов (включено автоматически) | Реальное время | Последние обновления | Встроено |
Укажите конкретные пакеты для анализа:
# Одной командой с seeds
export SEEDS="lodash,express,axios"
./scripts/run_pipeline.sh
# Или из файла
echo -e "react\nvue\nangular" > packages.txt
export SEEDS_FILE=packages.txt
./scripts/run_pipeline.sh
Как я тестировал изначально: Использовал SEEDS="is-odd,is-even" для быстрой проверки.
Сканируйте пакеты с постраничной загрузкой из реестра npm:
# Очистите предыдущие запуски
rm -rf downloads/* out/*
# Сканировать 2 страницы по 10 пакетов (20 пакетов)
export MAX_CHUNKS=2 # Количество страниц
export CHUNK_LIMIT=10 # Пакетов на страницу
unset SEEDS # Важно: отключить режим seeds
# Запустите каждый шаг отдельно для лучшей видимости
docker compose run --rm enumerator # Обнаруживает и ставит в очередь
docker compose run --rm fetcher # Загружает tar-архивы
docker compose run --rm analyzer # Сканирует на угрозы
Пример вывода:
config: chunkLimit=10, maxChunks=2
checking recent changes feed...
changes feed: enqueued 2 new versions
enumerating via _all_docs (fresh scan)
page 1/2 count: 10
page 2/2 count: 10
done, enqueued 22 (22 new versions)
Сканируйте весь реестр npm:
export MAX_CHUNKS=0 # 0 = неограниченно
export CHUNK_LIMIT=100 # Увеличенные партии для эффективности
./scripts/run_pipeline.sh
Предупреждение: Это будет выполняться часами/днями и просканирует сотни тысяч пакетов. Следите за дисковым пространством и размером базы данных.
Enumerator сохраняет состояние в ./out/enumerator_state.json с позицией курсора:
{
"last_seq": "0",
"last_startkey": "package-name",
"last_run": "2025-11-23T19:24:49.123Z",
"last_processed": 22,
"last_new": 22
}
Просто перезапустите конвейер, и он возобновит с последнего курсора:
./scripts/run_pipeline.sh # Автоматически возобновляет
Чтобы принудительно начать новое сканирование:
rm -f out/enumerator_state.json
./scripts/run_pipeline.sh
Из двухстраничного сканирования 22 пакетов, вот что обнаружил PackageInferno:
-- Лучшие подозрительные пакеты по баллам
SELECT p.name, s.score, s.label, COUNT(f.id) as findings
FROM packages p
JOIN versions v ON p.id = v.package_id
JOIN scores s ON v.id = s.version_id
LEFT JOIN findings f ON v.id = f.version_id
GROUP BY p.name, s.score, s.label
ORDER BY s.score DESC;
-- Результаты:
name | score | label | findings
-----------------------+-------+------------+----------
rendition | 606 | malicious | 153
vs-deploy | 454 | malicious | 119
--123hoodmane-pyodide | 213 | malicious | 46
Почему rendition оказался таким подозрительным?
url_outside_allowlist - Домены не из белого спискаsuspicious_pattern - Шаблоны оболочки/evaladvanced_obfuscation - Hex-кодирование, XOR, строковые массивыbig_base64_blob - Большие закодированные полезные нагрузкиurl_in_code - Встроенные URL